¿Cómo generar miniaturas cuando solo se necesita?

18

Tengo 1000 imágenes ¿Cómo puedo hacer que wordpress genere el pulgar solo cuando sea necesario? Por ejemplo, el control deslizante de inicio solo usará 10 imágenes. No quiero que las otras 1000 imágenes tengan esa miniatura generada, ya que es una pérdida de espacio y recursos.

¿Hay una manera de disparar add_image_size solo cuando sea necesario?

Gracias

ACTUALIZACIÓN Como mencionas, realmente no es add_image_size lo que necesita para ser disparado. Lo que sería genial es disparar el tamaño de la imagen cuando uso the_post_thumbnail ('slider-thumb'); Tal vez esto ralentice la primera vista de la imagen, pero esa vista generalmente la genero cuando reviso la publicación, así que no me importa.

Entonces, entre mis publicaciones, el control deslizante, las miniaturas de blog, las miniaturas de cartera, etc., obtuve 1000 imágenes y quiero que solo se cambien el tamaño de 10 imágenes para el control deslizante, veo muchos recursos desperdiciados para generar el tamaño de miniatura para las otras 990 imágenes.

Espero que esté claro ahora, perdón por mi inglés

chifliiiii
fuente
2
¿Cómo se generan las miniaturas de las 990 imágenes adicionales como una pérdida de espacio y recursos más que las 990 imágenes no utilizadas en primer lugar? ¿No tendría más sentido cargar solo las imágenes que estás usando activamente?
SickHippie
Aunque los programadores más hábiles presentan argumentos válidos contra su idea, me parece interesante. Vi algunos complementos y temas que cargan imágenes sin generar pulgares (no estoy seguro de cuál en este momento). Pero mi gran duda sobre tu pregunta es: ¿ cuándo la vas a necesitar? . ¿Cuál será el filtro?
brasofilo
1
Me entendiste mal. Uso las 990 imágenes en las publicaciones, simplemente no uso el control deslizante de inicio. Algunos de ellos que necesito pulgares para la cartera, algún otro de los pulgares de blogs, etc
chifliiiii

Respuestas:

12

Eche un vistazo al complemento Dynamic Image Resizer de Otto

Este complemento cambia la forma en que WordPress crea imágenes para que genere las imágenes solo cuando realmente se usan en algún lugar, sobre la marcha. Las imágenes creadas de este modo se guardarán en los directorios de carga normales, para su posterior envío rápido por el servidor web. El resultado es que se ahorra espacio (ya que las imágenes solo se crean cuando es necesario) y la carga de imágenes es mucho más rápida (ya que ya no genera las imágenes al cargarlas).

Chris_O
fuente
2
Tenga en cuenta que ese complemento tiene un problema al agregar imágenes a publicaciones antiguas. Parches de bienvenida.
Otto
Eso es exactamente lo que estaba buscando. Voy a darle una oportunidad. ¿Entonces solo funciona en nuevas publicaciones?
chifliiiii
1
Para aquellos que se encuentran con esta publicación ahora, aquí hay un complemento similar que parece estar siendo desarrollado activamente: wordpress.org/plugins/fly-dynamic-image-resizer
Tim Malone
7

Ponga esto en su archivo de funciones de tema. Evitará que Wordpress cree cualquier cosa que no sean los 3 tamaños predeterminados al cargar.

Cuando se solicita una imagen en un tamaño particular, que aún no se genera, se creará solo esa vez.

        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']
            );
        }
Patricio
fuente
Este archivador debe ser estándar en WordPress. ¿Por qué generar cada tamaño para cada imagen? Estoy agregando este código a mis temas personalizados. Gracias
Michaelkay
2
Bonito, pero ahora seguirá generando todas las imágenes si solo necesito un tamaño personalizado ...
Gijs
Sucede cuando uso objetos de imagen de campos personalizados avanzados
Gijs
No funciona SI add_image_size se definió previamente con las dimensiones de la imagen recién cambiadas
Benjamin Intal
@Michaelkay hay una penalización de rendimiento en este enfoque. Cuando se cargan las imágenes y luego se generan para cada tamaño, significa que el cargador es el que tiene paciencia. Este código hace que sus visitantes tengan que tener más paciencia, y Google ha probado que los sitios que tardan más de 2 segundos en cargar, reducen el 50% de las personas. Además, si su sitio tiene cientos de visitas simultáneas, esto eliminará sus servidores.
Tom Roggero
2

Lamentablemente, la respuesta de @ Patrick rompe las funciones srcset introducidas en WP 4.4. Afortunadamente, ¡solo necesitamos agregar dos funciones adicionales!

Primero, necesitamos reintroducir temporalmente todos los tamaños de miniatura registrados en los metadatos de la imagen para que puedan considerarse:

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

Luego, necesitamos revisar las coincidencias y generar las miniaturas que faltan:

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);
Josh
fuente
¡Solo un aviso para hacerle saber que esto romperá la cosecha dura! Me llevó horas descubrir que este era el culpable. Estoy trabajando en una solución ...
Constantin Groß
1

En realidad, add_image_size()no genera la miniatura, solo registra un tamaño de imagen disponible para WordPress.

Por lo general, las miniaturas se generan cuando la imagen se carga por primera vez. Es un proceso automático para que no tenga que preocuparse por generarlos más tarde. Piénselo de esta manera: si se necesitan 1-2 segundos para generar una miniatura en un servidor lento, y espera hasta que se solicite, obliga al solicitante a esperar 1-2 segundos adicionales por imagen para ver el contenido. Es mucho más fácil hacer esto con anticipación, es decir, cuando se carga la imagen.

Al mismo tiempo, si absolutamente debe procesar las miniaturas en un momento diferente, es posible que desee echar un vistazo al complemento Regenerate Thumbnails de Viper . Utiliza una acción a pedido para regenerar todas las miniaturas de sus imágenes ... pero podría usar un código similar para generar miniaturas solo cuando sea necesario.

EAMann
fuente
Creo que no entendiste el punto. Quiere controlar para qué imágenes se necesitan miniaturas. Por lo tanto, algunas imágenes no necesitan cambiar su tamaño.
Maestro borracho
La mayoría de las personas prueban las páginas cuando insertan las fotos (me siento bastante seguro diciendo todo) Causarán la generación de los archivos necesarios una vez y listo. En mi caso, tengo un tamaño de imagen de encabezado registrado. Aproximadamente 1 de cada 20 imágenes que subo son en realidad para el encabezado. Entonces, 19 de cada 20 imágenes en mi biblioteca es una pérdida de espacio.
JpaytonWPD
1

¿Hay una manera de disparar add_image_size solo cuando sea necesario?

No exactamente. Pero puede filtrar la lista de tamaños registrados justo antes de que se generen las miniaturas. La función wp_generate_attachment_metadata () (que llama a la función que genera las miniaturas) tiene un filtro llamado "intermedia_image_sizes_advanced", que le permite manipular la matriz de tamaños justo antes de que se generen los archivos. Puede usar este filtro siempre que agregue una imagen de un "tipo" determinado y luego eliminarlo inmediatamente después.

Supongo que su mayor desafío sería descubrir cómo diferenciar entre las imágenes que necesitan los tamaños adicionales y las que no.

MathSmath
fuente
Tendría que agregar una opción o casilla de verificación cuando subo medios para elegir qué pulgares quiero generar, por ejemplo. Suena bien, pero no tengo idea de cómo hacerlo
chifliiiii
1

Puede usar mi (no Ottos) "Dynamic Image Resize" 1) complemento.

"Dynamic Image Resize" es un complemento de WordPress (MU-) que ofrece un código corto y una etiqueta de plantilla para cambiar el tamaño de las imágenes "en el vuelo" sin la necesidad de TimThumb, pero con las funciones principales de WP.

El complemento viene con una etiqueta de plantilla y un código corto también.

1) Me acabo de enterar del complemento Ottos. La colisión de nombres no fue intencionada.

emperador
fuente
1

Puede probar este complemento: https://wordpress.org/plugins/optimize-images-resizing

Cambia el tamaño de las imágenes según el tamaño de la imagen registrada, pero solo cuando es necesario. También puede limpiar los tamaños de imagen existentes para que puedan regenerarse.

usuario2128576
fuente
0

El complemento WP Performance Pack ofrece un "manejo mejorado de la imagen", que se basa en Ottos Dynamic Image Resizer, pero incluye muchas mejoras, por ejemplo: en primer lugar, es compatible con la última versión de WordPress (3.9.1), utiliza WP_Image_Editor, el ahorro de miniaturas puede se puede desactivar (pero se pueden almacenar en caché y CDN Support está en funcionamiento), regenerar la integración de miniaturas (para eliminar miniaturas existentes) y algunas más.

Björn
fuente
-1

Puedes probar también Aqua Resizer - https://github.com/syamilmj/Aqua-Resizer/

Es solo un archivo.

Puedes usarlo así:

$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
antongorodezkiy
fuente
-1

Aquí otro enfoque más: se engancha en el manejo de errores 404 HTTP. Es decir, cuando la miniatura no está disponible, busque la imagen original y cree la miniatura. Tenga en cuenta que esto realmente no resuelve su problema, ya que no impide la generación de miniaturas durante la carga.

Tenga en cuenta también que este complemento puede ser utilizado por usuarios malintencionados para crear cualquier cantidad de miniaturas y, por lo tanto, agotar su espacio en disco.

Nota: este complemento se puede instalar fácilmente con 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();
}
Jack Miller
fuente