Как генерировать эскизы только при необходимости?


18

У меня есть 1000 изображений. Как я могу сделать WordPress для генерации большого пальца только при необходимости. Например, домашний слайдер будет использовать только 10 изображений, и я не хочу, чтобы на других 1000 изображениях этот миниатюра создавался как пустая трата пространства и ресурсов.

Есть способ запустить add_image_size только при необходимости?

Благодарность

ОБНОВЛЕНИЕ Как вы упоминаете, на самом деле add_image_size не то, что нужно для запуска. Что было бы здорово, так это запустить изменение размера изображения, когда я использую the_post_thumbnail ('slider-thumb'); Возможно, это замедление при первом просмотре изображения, но это представление обычно генерируется мной, когда я на самом деле просматриваю сообщение, поэтому мне все равно.

Итак, между моими постами, слайдером, блогами, миниатюрами портфолио и т. Д. У меня есть 1000 изображений, и я хочу, чтобы для слайдера было изменено только 10 изображений, я вижу много потраченных впустую ресурсов, чтобы сгенерировать размер миниатюр для других 990 изображений.

Надеюсь, теперь все ясно, извините за мой английский


2
Как миниатюры, созданные на основе дополнительных 990 изображений, являются более пустой тратой пространства и ресурсов, чем 990 неиспользуемых изображений? Разве не имеет смысла загружать только те изображения, которые вы активно используете?
SickHippie

Хотя более опытные программисты приводят веские аргументы против вашей идеи, я нахожу это интересным. Я видел некоторые плагины и темы, которые загружают изображения, не генерируя большие пальцы (не знаю, какие именно сейчас). Но мое большое сомнение в твоем вопросе: когда оно тебе понадобится? , Какой будет фильтр?
brasofilo

1
Ты неправильно меня понял. Я использую 990 изображений в постах, я просто не использую слайдер в доме. Некоторые из них мне нужны большие пальцы для портфолио, другие другие для блога и т. Д.
chifliiiii

Ответы:


12

Взгляните на плагин Otto's Dynamic Image Resizer

Этот плагин изменяет способ, которым WordPress создает изображения, чтобы он генерировал изображения только тогда, когда они действительно используются где-то, на лету. Созданные таким образом изображения будут сохранены в обычных каталогах загрузки для последующей быстрой отправки веб-сервером. В результате экономится место (поскольку изображения создаются только при необходимости), а загрузка изображений происходит намного быстрее (поскольку изображения больше не генерируются при загрузке).


2
Обратите внимание, что у этого плагина есть проблема с добавлением изображений в старые сообщения. Патчи приветствуются.
Отто

Это именно то, что я искал. Я дам ему попробовать. Так это работает только на новых сообщениях?
chifliiiii

1
Для тех, кто сталкивается с этим постом сейчас, есть похожий плагин, который, похоже, активно разрабатывается: wordpress.org/plugins/fly-dynamic-image-resizer
Тим Мэлоун,

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

2
Хорошо, но теперь он по-прежнему будет генерировать все изображения, если мне нужен только один нестандартный размер ..
Gijs

Это происходит, когда я использую объекты изображений из расширенных пользовательских полей
Gijs

Не работает, если add_image_size был ранее определен с только что измененными размерами изображения
Benjamin Intal

@Michaelkay в этом подходе есть потеря производительности. Когда изображения загружаются, а затем генерируются для каждого размера, означает, что загрузчик терпеливо. Этот код заставляет ваших посетителей проявлять больше терпения, и Google доказал, что сайты, загрузка которых занимает более 2 секунд, отбрасывают 50% людей. Кроме того, если ваш сайт имеет сотни одновременных посещений, это приведет к отключению ваших серверов.
Том

2

К сожалению, ответ @ Patrick нарушает функции srcset, представленные в WP 4.4. К счастью, нам просто нужно добавить две дополнительные функции!

Во-первых, нам нужно временно повторно ввести все зарегистрированные размеры миниатюр в метаданные изображения, чтобы их можно было рассмотреть:

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);

Просто хедз-ап, чтобы вы знали, что это сломает жесткую обрезку! Мне потребовались часы, чтобы понять, что это виновник. Я работаю над решением ...
Константин Грос

1

На самом деле, add_image_size()не генерирует миниатюры, а просто регистрирует размер изображения, доступный для WordPress.

Как правило, миниатюры создаются при первой загрузке изображения. Это автоматический процесс, поэтому вам не нужно беспокоиться о его генерации позже. Подумайте об этом так: если для создания миниатюры на медленном сервере требуется 1-2 секунды, и вы ждете, пока его не запросят, вы заставляете запрашивающего ждать еще 1-2 секунды на изображение, чтобы увидеть содержимое. Гораздо проще сделать это заранее - т.е. когда изображение загружено.

В то же время, если вам абсолютно необходимо обрабатывать эскизы в другое время, вы можете посмотреть на плагин Viper's Regenerate Thumbnails . Он использует действие по требованию для восстановления всех миниатюр изображений ... но вы можете использовать аналогичный код для создания миниатюр только при необходимости.


Я думаю, вы не поняли. Он хочет контролировать, для каких изображений нужны миниатюры. Таким образом, некоторые изображения вообще не нуждаются в изменении размера.
Пьяный Мастер

Большинство людей проверяют страницы, когда вставляют фотографии (я чувствую себя довольно спасительно, говоря все). Они приведут к генерации необходимых файлов, которые когда-то будут готовы. В моем случае зарегистрирован размер изображения заголовка. Примерно 1 из 20 изображений, которые я загружаю, на самом деле для заголовка. Так что 19 из 20 изображений в моей библиотеке - пустая трата места.
JpaytonWPD

1

Есть способ запустить add_image_size только при необходимости?

Не совсем. Но вы можете отфильтровать список зарегистрированных размеров прямо перед созданием эскизов. Функция wp_generate_attachment_metadata () (которая вызывает функцию, генерирующую миниатюры) имеет фильтр с именем «промежуточный_размер_символов», который позволяет вам манипулировать массивом размеров непосредственно перед созданием файлов. Вы можете использовать этот фильтр всякий раз, когда вы добавляете изображение определенного «типа», а затем сразу же удаляете его.

Я полагаю, что вашей самой большой проблемой было бы выяснить, как отличить изображения, которым требуются дополнительные размеры, и изображения, которые не нуждаются.


Мне нужно было бы добавить опцию или флажок, когда я загружаю медиа, чтобы выбрать, какие пальцы я хочу сгенерировать, например. Звучит хорошо, но я не понял, как это сделать
chifliiiii

1

Вы можете использовать мой (не Ottos) плагин "Dynamic Image Resize" 1) .

«Динамическое изменение размера изображения» - это плагин WordPress (MU-), который предлагает шорткод и тег шаблона для изменения размера изображений «в полете» без необходимости использования TimThumb, но с основными функциями WP.

Плагин поставляется с тегом шаблона и шорткодом .

1) Только что узнал о плагине Ottos. Имена столкновений не были предназначены.


1

Вы можете попробовать этот плагин: https://wordpress.org/plugins/optimize-images-resizing

Размер изображения изменяется в зависимости от размера зарегистрированного изображения, но только при необходимости. Также можно очистить существующие размеры изображений, чтобы они могли регенерировать.


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();
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.