之前写过一篇关于《WordPress 图片裁剪插件Aqua-Resizer使用方法》,最近在完善主题,又把这个功能优化了一下:
1、添加了外链图片的剪裁;
2、添加定期清理剪裁图片的功能;
3、结合特色图片,优化使用;
4、修复了稳定性。
1、下面先附代码
Aqua Resizer (支持远程图片版 - 修复稳定版)
<?php
/**
* Title : Aqua Resizer (支持远程图片版 - 修复稳定版)
* Description : Resizes WordPress images on the fly (支持远程图片裁剪)
* Version : 1.2.2 + 远程图片扩展 + 稳定性修复
* Author : 微言心语
* Author URI : https://wuean.com/
* License : WTFPL - http://sam.zoy.org/wtfpl/
*/
if(!class_exists('Aq_Resize')) {
class Aq_Exception extends Exception {}
class Aq_Resize
{
static private $instance = null;
public $throwOnError = false;
private function __construct() {}
private function __clone() {}
static public function getInstance() {
if(self::$instance == null) {
self::$instance = new self;
}
return self::$instance;
}
public function process( $url, $width = null, $height = null, $crop = null, $single = true, $upscale = false ) {
try {
if (!$url) throw new Aq_Exception('$url 参数不能为空');
if (!$width) throw new Aq_Exception('$width 参数不能为空');
// 清理URL(移除 ?xxx #xxx 关键修复!)
$url = strtok($url, '?#');
$url = trim($url);
if ( true === $upscale ) add_filter( 'image_resize_dimensions', array($this, 'aq_upscale'), 10, 6 );
$upload_info = wp_upload_dir();
$upload_dir = $upload_info['basedir'];
$upload_url = $upload_info['baseurl'];
$http_prefix = "http://";
$https_prefix = "https://";
$relative_prefix = "//";
if(!strncmp($url,$https_prefix,strlen($https_prefix))){
$upload_url = str_replace($http_prefix,$https_prefix,$upload_url);
} elseif(!strncmp($url,$http_prefix,strlen($http_prefix))){
$upload_url = str_replace($https_prefix,$http_prefix,$upload_url);
} elseif(!strncmp($url,$relative_prefix,strlen($relative_prefix))){
$upload_url = str_replace(array("$http_prefix","$https_prefix"),$relative_prefix,$upload_url);
}
$is_remote = false;
$local_img_path = '';
$local_img_url = '';
// 判断远程图片(修复判断逻辑)
$is_local = (strpos($url, $upload_url) !== false);
if (!$is_local) {
$is_remote = true;
$url_hash = md5($url);
// 智能获取图片扩展名(修复)
$file_ext = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);
$allow = ['jpg','jpeg','png','gif','webp'];
$file_ext = strtolower($file_ext);
$file_ext = in_array($file_ext, $allow) ? $file_ext : 'jpg';
$theme_dir = get_template_directory();
$remote_cache_dir = trailingslashit($theme_dir . '/remote-images/');
if (!file_exists($remote_cache_dir)) {
wp_mkdir_p($remote_cache_dir);
}
$local_img_path = $remote_cache_dir . $url_hash . '.' . $file_ext;
// 不存在才下载
if (!file_exists($local_img_path)) {
$response = wp_remote_get($url, array(
'timeout' => 15,
'sslverify' => false,
'user-agent' => 'Mozilla/5.0',
'reject_unsafe_urls' => false,
));
if (is_wp_error($response)) {
throw new Aq_Exception('下载失败:'.$response->get_error_message());
}
$code = wp_remote_retrieve_response_code($response);
if($code < 200 || $code >= 400) {
throw new Aq_Exception("HTTP 错误:$code");
}
$image_content = wp_remote_retrieve_body($response);
if (empty($image_content)) {
throw new Aq_Exception('图片内容为空');
}
file_put_contents($local_img_path, $image_content);
if (!getimagesize($local_img_path)) {
@unlink($local_img_path);
throw new Aq_Exception('非有效图片');
}
}
$img_path = $local_img_path;
$theme_url = get_template_directory_uri();
$remote_cache_url = trailingslashit($theme_url . '/remote-images/');
$local_img_url = $remote_cache_url . $url_hash . '.' . $file_ext;
} else {
$rel_path = str_replace( $upload_url, '', $url );
$img_path = $upload_dir . $rel_path;
$local_img_url = $url;
}
if ( ! file_exists( $img_path ) or ! getimagesize( $img_path ) ) {
throw new Aq_Exception('图片不存在或无效');
}
$info = pathinfo( $img_path );
$ext = $info['extension'];
list( $orig_w, $orig_h ) = getimagesize( $img_path );
$dims = image_resize_dimensions( $orig_w, $orig_h, $width, $height, $crop );
if (!$dims) {
$img_url = $local_img_url;
$dst_w = $orig_w;
$dst_h = $orig_h;
} else {
$dst_w = $dims[4];
$dst_h = $dims[5];
if ( ( ( null === $height && $orig_w == $width ) xor ( null === $width && $orig_h == $height ) ) xor ( $height == $orig_h && $width == $orig_w ) ) {
$img_url = $local_img_url;
} else {
$suffix = "{$dst_w}x{$dst_h}";
$img_dir = dirname($img_path);
$img_name = basename($img_path, '.' . $ext);
$destfilename = "{$img_dir}/{$img_name}-{$suffix}.{$ext}";
if ( file_exists( $destfilename ) && getimagesize( $destfilename ) ) {
if ($is_remote) {
$img_url = str_replace($theme_dir, $theme_url, $destfilename);
} else {
$img_url = str_replace($upload_dir, $upload_url, $destfilename);
}
} else {
$editor = wp_get_image_editor( $img_path );
if ( is_wp_error( $editor ) ) {
throw new Aq_Exception('图片编辑器加载失败');
}
$resize_result = $editor->resize( $width, $height, $crop );
if ( is_wp_error( $resize_result ) ) {
throw new Aq_Exception('裁剪失败');
}
$resized_file = $editor->save();
if ( is_wp_error( $resized_file ) ) {
throw new Aq_Exception('保存失败');
}
if ($is_remote) {
$img_url = str_replace($theme_dir, $theme_url, $resized_file['path']);
} else {
$img_url = str_replace($upload_dir, $upload_url, $resized_file['path']);
}
}
}
}
if ( true === $upscale ) remove_filter( 'image_resize_dimensions', array( $this, 'aq_upscale' ) );
if ( $single ) {
$image = $img_url;
} else {
$image = array (0 => $img_url, 1 => $dst_w, 2 => $dst_h);
}
return $image;
}
catch (Aq_Exception $ex) {
error_log('Aq_Resize 错误: ' . $ex->getMessage());
if ($this->throwOnError) {
throw $ex;
} else {
// 失败返回原图URL,不返回false(关键修复)
return $url;
}
}
}
function aq_upscale( $default, $orig_w, $orig_h, $dest_w, $dest_h, $crop ) {
if ( ! $crop ) return null;
$aspect_ratio = $orig_w / $orig_h;
$new_w = $dest_w;
$new_h = $dest_h;
if ( ! $new_w ) $new_w = intval( $new_h * $aspect_ratio );
if ( ! $new_h ) $new_h = intval( $new_w / $aspect_ratio );
$size_ratio = max( $new_w / $orig_w, $new_h / $orig_h );
$crop_w = round( $new_w / $size_ratio );
$crop_h = round( $new_h / $size_ratio );
$s_x = floor( ( $orig_w - $crop_w ) / 2 );
$s_y = floor( ( $orig_h - $crop_h ) / 2 );
return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h );
}
}
}
if(!function_exists('aq_resize')) {
function aq_resize( $url, $width = null, $height = null, $crop = null, $single = true, $upscale = false ) {
if ( defined( 'ICL_SITEPRESS_VERSION' ) ){
global $sitepress;
$url = $sitepress->convert_url( $url, $sitepress->get_default_language() );
}
$aq_resize = Aq_Resize::getInstance();
return $aq_resize->process( $url, $width, $height, $crop, $single, $upscale );
}
}
function wutheme_thumbnail($width = 1200, $height = 400)
{
global $post;
$default_thumbnail = get_template_directory_uri() . '/assets/images/default-thumb.jpg';
$img_attrs = sprintf(
'title="%s" alt="%s" width="%d" height="%d" style="width:%dpx; height:%dpx; object-fit:cover;"',
esc_attr(get_the_title()),
esc_attr(get_the_title()),
$width,
$height,
$width,
$height
);
// 1. 特色图
if (has_post_thumbnail()) {
$src = wp_get_attachment_url(get_post_thumbnail_id($post->ID));
$resized = aq_resize($src, $width, $height, true);
$resized = $resized ?: $default_thumbnail;
echo "<img src=\"".esc_url($resized)."\" {$img_attrs}/>";
return;
}
// 2. 匹配文章第一张图片(超级强化正则,支持懒加载、远程图、data-src)
$content = $post->post_content;
preg_match('/<img[\s\S]*?src=[\'"](.*?)[\'"][\s\S]*?>/i', $content, $match);
$img_src = isset($match[1]) ? trim(strtok($match[1], '?#')) : '';
if ($img_src && (strpos($img_src, 'http') === 0 || strpos($img_src, '//') === 0)) {
$resized = aq_resize($img_src, $width, $height, true);
$resized = $resized ?: $default_thumbnail;
echo "<img src=\"".esc_url($resized)."\" {$img_attrs}/>";
return;
}
// 3. 兜底默认图
echo "<img src=\"".esc_url($default_thumbnail)."\" {$img_attrs}/>";
}
/**
* 清理主题下remote-images缓存(简化版)
*/
function wutheme_clean_remote_images_cache_simple($expire_days = 7) {
$theme_remote_dir = get_template_directory() . '/remote-images/';
if (!file_exists($theme_remote_dir) || !is_dir($theme_remote_dir)) {
return false;
}
$expire_time = time() - ($expire_days * 86400);
$files = glob($theme_remote_dir . '*.{jpg,jpeg,png,gif,webp}', GLOB_BRACE);
$deleted = 0;
foreach ($files as $file) {
if (filemtime($file) < $expire_time && @unlink($file)) {
$deleted++;
}
}
return $deleted;
}
// 可选:每次裁剪图片时,触发清理(轻量触发)
function wutheme_clean_cache_on_resize() {
// 每10次裁剪触发一次清理(避免频繁执行)
static $count = 0;
if ($count++ % 10 === 0) {
wutheme_clean_remote_images_cache_simple(7);
}
}
add_action('after_setup_theme', 'wutheme_clean_cache_on_resize');
这里要注意一下,要在主题根目录建立一个存放剪裁图片的文件夹remote-images.
还要在主题的图片目录下存放一张默认图片default-thumb.jpg,我的路径是主题/images/default-thumb.jpg。你可根据自己主题结构修改相应代码
2、使用方法
//修改240和140来裁剪图片宽和高
<?php wutheme_thumbnail(240, 140); ?>
//如果不填写就显示为1200*400,在PHP文件里可设置
3、代码下载
整理好的代码直接添加在funcion.php后面,或者建立文件调用就可以.
