首页 Wordpress WordPress 图片剪裁Aqua-Resizer插件优化升级版

WordPress 图片剪裁Aqua-Resizer插件优化升级版

之前写过一篇关于《WordPress 图片裁剪插件Aqua-Resizer使用方法》,最近在完善主题,又把这个功能优化了一下: 1、添加了外链图片的剪裁; 2、添加定期清理剪裁图片的功能; 3、结合特色图片,优化使用; 4、修复了稳定性。

1、下面先附代码

Aqua Resizer (支持远程图片版 - 修复稳定版)
php
<?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');
html
这里要注意一下,要在主题根目录建立一个存放剪裁图片的文件夹remote-images.
还要在主题的图片目录下存放一张默认图片default-thumb.jpg,我的路径是主题/images/default-thumb.jpg。你可根据自己主题结构修改相应代码

2、使用方法

php
//修改240和140来裁剪图片宽和高
<?php wutheme_thumbnail(240, 140); ?>
//如果不填写就显示为1200*400,在PHP文件里可设置

3、代码下载

整理好的代码直接添加在funcion.php后面,或者建立文件调用就可以.

相关推荐

发表回复

邮箱地址不会被公开。