仅在需要时如何生成缩略图?


18

我有1000张图片。我如何才能使wordpress仅在需要时生成拇指。例如,主页滑块将仅使用10张图像,我不希望其他1000张图像生成该缩略图,因为这浪费了空间和资源。

有一种方法仅在需要时触发add_image_size?

谢谢

UPDATE正如您提到的,add_image_size并不是真正需要触发的内容。最好是在我使用the_post_thumbnail('slider-thumb')时触发图像调整大小 也许这会减慢图像的第一个视图,但该视图通常是由我在实际查看帖子时生成的,因此我不在乎。

因此,在我的帖子,滑块,博客缩略图,作品集缩略图等之间,我得到了1000张图像,并且我只想为滑块重新调整10张图像的大小,我发现浪费了很多资源来生成其他990张图像的缩略图大小。

希望现在明白了,对不起我的英语


2
与最初的990张未使用的图像相比,如何从额外的990张图像生成的缩略图浪费更多的空间和资源?仅上传您正在使用的图像是否更有意义?
SickHippie 2012年

即使更多熟练的程序员提出反对您想法的有效论据,我也觉得很有趣。我看到了一些插件和主题,这些插件和主题可以上传图像而不会产生拇指(现在不确定是哪个)。但是我对您的问题的最大怀疑是:您什么时候需要它?。什么是过滤器?
brasofilo 2012年

1
你误会我了。我在帖子中使用了990张图片,只是在首页滑块中不使用。其中一些我需要投资组合的大拇指,其他一些则需要博客的大拇指,等等
chifliiiii 2012年

Answers:


12

看看Otto的Dynamic Image Resizer插件

这个插件改变了WordPress创建图像的方式,使其仅在实际在某个地方即时使用时才生成图像。这样创建的图像将保存在正常的上传目录中,以供Web服务器稍后快速发送。结果是节省了空间(因为仅在需要时才创建图像),并且上传图像要快得多(因为它不再在上传时生成图像)。


2
请注意,该插件在将图像添加到旧帖子时遇到问题。欢迎打补丁。
奥托(Otto)

那正是我想要的。我会试一试。因此,它仅适用于新帖子?
chifliiiii 2012年

1
对于现在遇到这篇文章的人来说,这是一个正在积极开发的类似插件:wordpress.org/plugins/fly-dynamic-image-resizer
Tim Malone

7

将其放在主题函数文件中。上传时,它将阻止Wordpress创建除3个默认大小以外的任何内容。

然后以尚未生成的特定尺寸请求图像时,将仅创建该图像一次。

        add_filter('image_downsize', 'ml_media_downsize', 10, 3);
        function ml_media_downsize($out, $id, $size) {
            // If image size exists let WP serve it like normally
            $imagedata = wp_get_attachment_metadata($id);
            if (is_array($imagedata) && isset($imagedata['sizes'][$size]))
                return false;

            // Check that the requested size exists, or abort
            global $_wp_additional_image_sizes;
            if (!isset($_wp_additional_image_sizes[$size]))
                return false;

            // Make the new thumb
            if (!$resized = image_make_intermediate_size(
                get_attached_file($id),
                $_wp_additional_image_sizes[$size]['width'],
                $_wp_additional_image_sizes[$size]['height'],
                $_wp_additional_image_sizes[$size]['crop']
            ))
                return false;

            // Save image meta, or WP can't see that the thumb exists now
            $imagedata['sizes'][$size] = $resized;
            wp_update_attachment_metadata($id, $imagedata);

            // Return the array for displaying the resized image
            $att_url = wp_get_attachment_url($id);
            return array(dirname($att_url) . '/' . $resized['file'], $resized['width'], $resized['height'], true);
        }


        add_filter('intermediate_image_sizes_advanced', 'ml_media_prevent_resize_on_upload');
        function ml_media_prevent_resize_on_upload($sizes) {
            // Removing these defaults might cause problems, so we don't
            return array(
                'thumbnail' => $sizes['thumbnail'],
                'medium' => $sizes['medium'],
                'large' => $sizes['large']
            );
        }

该文件管理器应该是WordPress中的标准文件。为什么要为每个图像生成每种尺寸?我将此代码添加到我的自定义主题中。谢谢
Michaelkay 2014年

2
不错,但现在它仍然会产生的所有图像,如果我只需要一个自定义大小..
的Gijs

当我使用来自高级自定义字段的图像对象时就会发生这种情况
Gijs 2015年

如果先前已定义add_image_size且图像尺寸刚刚更改,则无法使用
Benjamin Intal,2015年

@Michaelkay这种方法会降低性能。上载图像然后生成各种尺寸的图像时,意味着上载者是耐心的。此代码使您的访问者必须更加耐心,并且Google已证明网站加载时间超过2秒,从而使50%的人流失。另外,如果您的站点有数百个并发访问,这将导致服务器宕机。
Tom Roggero

2

不幸的是,@ Patrick的答案破坏了WP 4.4中引入的srcset函数。幸运的是,我们只需要添加两个附加功能即可!

首先,我们需要暂时将所有已注册的缩略图大小重新引入图像元数据,以便可以将其考虑在内:

function bi_wp_calculate_image_srcset_meta($image_meta, $size_array, $image_src, $attachment_id){
    //all registered sizes
    global $_wp_additional_image_sizes;

    //some source file specs we'll use a lot
    $src_path = get_attached_file($attachment_id);
    $src_info = pathinfo($src_path);
    $src_root = trailingslashit($src_info['dirname']);
    $src_ext = $src_info['extension'];
    $src_mime = wp_check_filetype($src_path);
    $src_mime = $src_mime['type'];
    $src_base = wp_basename($src_path, ".$src_ext");

    //find what's missing
    foreach($_wp_additional_image_sizes AS $k=>$v)
    {
        if(!isset($image_meta['sizes'][$k]))
        {
            //first, let's find out how things would play out dimensionally
            $new_size = image_resize_dimensions($image_meta['width'], $image_meta['height'], $v['width'], $v['height'], $v['crop']);
            if(!$new_size)
                continue;
            $new_w = (int) $new_size[4];
            $new_h = (int) $new_size[5];

            //bad values
            if(!$new_h || !$new_w)
                continue;

            //generate a filename the same way WP_Image_Editor would
            $new_f = wp_basename("{$src_root}{$src_base}-{$new_w}x{$new_h}." . strtolower($src_ext));

            //finally, add it!
            $image_meta['sizes'][$k] = array(
                'file'      => $new_f,
                'width'     => $new_w,
                'height'    => $new_h,
                'mime-type' => $src_mime
            );
        }
    }

    return $image_meta;
}
add_filter('wp_calculate_image_srcset_meta', 'bi_wp_calculate_image_srcset_meta', 10, 4);

然后,我们需要遍历比赛并生成所有缺少的缩略图:

function bi_wp_calculate_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id){

    //get some source info
    $src_path = get_attached_file($attachment_id);
    $src_root = trailingslashit(pathinfo($src_path, PATHINFO_DIRNAME));

    //the actual image metadata (which might be altered here)
    $src_meta = wp_get_attachment_metadata($attachment_id);

    //an array of possible sizes to search through
    $sizes = $image_meta['sizes'];
    unset($sizes['thumbnail']);
    unset($sizes['medium']);
    unset($sizes['large']);

    $new = false;

    //loop through sources
    foreach($sources AS $k=>$v)
    {
        $name = wp_basename($v['url']);
        if(!file_exists("{$src_root}{$name}"))
        {
            //find the corresponding size
            foreach($sizes AS $k2=>$v2)
            {
                //we have a match!
                if($v2['file'] === $name)
                {
                    //make it
                    if(!$resized = image_make_intermediate_size(
                        $src_path,
                        $v2['width'],
                        $v2['height'],
                        $v2['crop']
                    )){
                        //remove from sources on failure
                        unset($sources[$k]);
                    }
                    else
                    {
                        //add the new thumb to the true meta
                        $new = true;
                        $src_meta['sizes'][$k2] = $resized;
                    }

                    //remove from the sizes array so we have
                    //less to search next time
                    unset($sizes[$k2]);
                    break;
                }//match
            }//each size
        }//each 404
    }//each source

    //if we generated something, update the attachment meta
    if($new)
        wp_update_attachment_metadata($attachment_id, $src_meta);

    return $sources;
}
add_filter('wp_calculate_image_srcset', 'bi_wp_calculate_image_srcset', 10, 5);

提醒一下,这将使您无法正常耕种!我花了几个小时才发现这是罪魁祸首。我正在研究解决方案...
ConstantinGroß18'Feb

1

实际上,add_image_size()它不会生成缩略图,而只是注册一个可供WordPress使用的图像大小。

通常,缩略图是在首次上传图像时生成的。这是一个自动过程,因此您不必担心以后生成它们。可以这样考虑-如果在速度较慢的服务器上生成缩略图需要1-2秒,而您一直等到收到请求,则强制被请求者每张图像再等待1-2秒再才能看到内容。提前进行操作(即上传图片时)要容易得多。

同时,如果您绝对必须在其他时间处理缩略图,则可能需要看一下Viper的Regenerate Thumbnails插件。它使用按需操作来重新生成所有图像缩略图……但是您可以使用类似的代码仅在需要时生成缩略图。


我认为您没有明白这一点。他想控制需要缩略图的图像。因此,有些图像根本不需要调整大小。
醉拳大师

大多数人会在插入照片时测试页面(我想说的还不错),它们会导致生成所需的文件,一次又一次地完成。就我而言,我已注册了标头图像尺寸。我上传的20张图片中大约有1张实际上是用于标题的。因此,我的图书馆中20张图片中有19张浪费了空间。
JpaytonWPD

1

有一种方法仅在需要时触发add_image_size?

不完全是。但是您可以在生成缩略图之前过滤已注册尺寸的列表。wp_generate_attachment_metadata()函数(调用生成缩略图的函数)具有一个名为“ intermediate_image_sizes_advanced”的过滤器,该过滤器使您可以在生成文件之前操纵大小数组。您可以在添加某种“类型”的图像时使用此过滤器,然后在之后立即将其删除。

我想您的最大挑战将是弄清楚如何区分需要额外尺寸的图像和不需要额外尺寸的图像。


例如,当我上载媒体时,我将不得不添加一个选项或复选框来选择要生成的夹心拇指。听起来不错,但我不知道该怎么做
chifliiiii

1

您可以使用我的(不是Ottos)“动态图像调整大小” 1)插件。

“动态图像调整大小”是一种WordPress(MU-)插件,提供了短代码和模板标签,可在不需要TimThumb的情况下“在飞行中”调整图像大小,但具有WP核心功能。

该插件还带有模板标签和简码

1)刚刚发现有关Ottos插件的信息。命名冲突不是故意的。



0

WP Performance Pack插件提供了基于Ottos Dynamic Image Resizer的“改进的图像处理”,但包括许多改进,例如:首先,它与最新的WordPress版本(3.9.1)兼容,使用WP_Image_Editor,可以保存缩略图可以关闭(但可以缓存它们并且可以使用CDN支持),重新生成Thumbails集成(以删除现有缩略图)等等。


-1

您也可以尝试Aqua Resizer- https://github.com/syamilmj/Aqua-Resizer/

这只是一个文件。

您可以像这样使用它:

$img_src = aq_resize( $img_src, $width = null, $height = null, $crop = null, $single = true, $upscale = false );

$img_src = aq_resize( $img_src, 150, 150); // resized
$img_src = aq_resize( $img_src, 150, 150, true); // cropped
$img_src = aq_resize( $img_src, 150, 150, null, null, true); // image with 120x120 for example will be upscaled up to 150x150

-1

这里是另一种方法:它与404 HTTP错误处理挂钩。即,当缩略图不可用时,找到原始图像并创建缩略图。请注意,这并不能真正解决您的问题,因为它无法阻止上传过程中生成缩略图。

还要注意,恶意用户可能使用此插件来创建任意数量的缩略图,从而耗尽磁盘空间。

注意:可以使用Pluginception轻松安装此插件。

<?php
/*
Plugin Name: Create thumbnails on demand
Plugin URI: 
Description: Create thumbnails instead of showing 404. Use in combination with "Broken Link Checker" to create all missing thumbnails.
Version: 0.1
Author: Jack Miller
Author URI: 
License: 
License URI: 
*/
add_filter('status_header', 'createThumbIf404');
function createThumbIf404($httpCodeString) //e.g. HTTP/1.1 200 OK 
{
    global $wp_query;
    error_reporting(E_ALL);
    ini_set('display_errors', 1);

    $httpCode = explode(" ", $httpCodeString);
    $httpCode = $httpCode[1];
    if ($httpCode == "404") {
        $requestUri = $_SERVER["REQUEST_URI"];
        $regex = '/^\/(wp-content\/uploads\/(?:[a-zA-Z0-9]*\/){2})(.*)-(.*)x(.*)\.jpg$/';
        preg_match($regex, $requestUri, $groups);
        if (sizeof($groups) === 5) {
            $baseDir  = $groups[1];
            $baseName = $groups[2];
            $sizeX    = $groups[3];
            $sizeY    = $groups[4];

            $oriImg = ctod_checkFile($baseDir, $baseName);
            if ($oriImg != null) {

                $image = wp_get_image_editor($baseDir . $oriImg);
                if (!is_wp_error($image)) {
                    $image->resize($sizeX, $sizeY, true);
                    $thumb = $baseDir . $baseName . '-' . $sizeX . 'x' . $sizeY . '.jpg';
                    $image->save($thumb);
                    ctod_sendImageAndExit($thumb);
                }
            }
        }
    }
}
//finds original image within $baseDir with $baseName.
//Returns file name including extension of original image or null.
function ctod_checkFile($baseDir, $baseName)
{
    $arr = array(
        ".jpg",
        ".JPG",
        ".jpeg",
        ".JPEG"
    );
    foreach ($arr as &$ext) {
        if (file_exists($baseDir . $baseName . $ext)) {
            return $baseName . $ext;
        }
    }
    return null;
}
//Read file at $path from disk and return it as HTTP JPG image request.
function ctod_sendImageAndExit($path)
{
    $fp = fopen($path, 'rb');
    header("Content-Type: image/jpeg");
    header("Content-Length: " . filesize($path));
    fpassthru($fp);
    exit();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.