¿Cómo generar miniaturas solo cuando sean necesarias?

26 may 2012, 00:52:50
Vistas: 28.3K
Votos: 22

Tengo 1000 imágenes. ¿Cómo puedo hacer que WordPress genere miniaturas solo cuando sean necesarias? Por ejemplo, el slider de la página principal solo usará 10 imágenes y no quiero que las otras 1000 imágenes tengan esa miniatura generada ya que es un desperdicio de espacio y recursos.

¿Existe alguna manera de ejecutar add_image_size solo cuando sea necesario?

Gracias

ACTUALIZACIÓN Como mencionan, no es realmente add_image_size lo que necesita ser ejecutado. Lo que sería genial es activar el redimensionamiento 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 yo cuando realmente reviso la entrada, así que no me importa.

Entonces, entre mis entradas, slider, miniaturas del blog, miniaturas del portafolio, etc., tengo 1000 imágenes y solo quiero que 10 imágenes sean redimensionadas para el slider. Veo muchos recursos desperdiciados al generar el tamaño de miniatura para las otras 990 imágenes.

Espero que ahora esté claro, disculpen mi inglés

3
Comentarios

¿Cómo es que generar miniaturas a partir de las 990 imágenes adicionales es más derroche de espacio y recursos que tener 990 imágenes sin usar en primer lugar? ¿No tendría más sentido subir solo las imágenes que estás utilizando activamente?

SickHippie SickHippie
26 may 2012 01:05:41

Aunque programadores más experimentados presentan argumentos válidos en contra de tu idea, la encuentro interesante. He visto algunos plugins y temas que suben imágenes sin generar miniaturas (no recuerdo cuáles ahora). Pero mi gran duda sobre tu pregunta es: ¿cuándo vas a necesitarlo?. ¿Cuál será el filtro?

brasofilo brasofilo
26 may 2012 01:26:22

Me entendiste mal. Yo uso las 990 imágenes en publicaciones, solo que no las uso en el slider de la página principal. Algunas las necesito en miniatura para el portafolio, otras para miniaturas del blog, etc.

chifliiiii chifliiiii
26 may 2012 01:55:53
Todas las respuestas a la pregunta 11
3
14

Echa un vistazo al plugin Dynamic Image Resizer de Otto

Este plugin cambia la forma en que WordPress crea imágenes para que solo las genere cuando realmente se utilizan en algún lugar, al vuelo. Las imágenes creadas de esta manera se guardarán en los directorios normales de subida, para un envío rápido posterior por parte del servidor web. El resultado es que se ahorra espacio (ya que las imágenes solo se crean cuando se necesitan) y la subida de imágenes es mucho más rápida (ya que no genera las imágenes durante la subida).

26 may 2012 02:42:42
Comentarios

Ten en cuenta que ese plugin tiene un problema al añadir imágenes a entradas antiguas. Se aceptan parches.

Otto Otto
26 may 2012 05:18:42

Eso es exactamente lo que estaba buscando. Lo probaré. ¿Entonces solo funciona en entradas nuevas?

chifliiiii chifliiiii
26 may 2012 19:04:34

Para aquellos que encuentren esta publicación ahora, aquí hay un plugin similar que parece estar en desarrollo activo: https://wordpress.org/plugins/fly-dynamic-image-resizer/

Tim Malone Tim Malone
23 mar 2016 03:08:16
5

Coloca esto en el archivo de funciones de tu tema. Evitará que WordPress cree cualquier tamaño adicional a los 3 predeterminados al subir imágenes.

Cuando luego se solicite una imagen en un tamaño específico que aún no se ha generado, se creará solo esa una vez.

        add_filter('image_downsize', 'ml_media_downsize', 10, 3);
        function ml_media_downsize($out, $id, $size) {
            // Si el tamaño de imagen existe, deja que WordPress lo sirva normalmente
            $imagedata = wp_get_attachment_metadata($id);
            if (is_array($imagedata) && isset($imagedata['sizes'][$size]))
                return false;

            // Verifica que el tamaño solicitado exista, o aborta
            global $_wp_additional_image_sizes;
            if (!isset($_wp_additional_image_sizes[$size]))
                return false;

            // Crea la nueva miniatura
            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;

            // Guarda los metadatos de la imagen, o WordPress no podrá ver que la miniatura existe ahora
            $imagedata['sizes'][$size] = $resized;
            wp_update_attachment_metadata($id, $imagedata);

            // Devuelve el array para mostrar la imagen redimensionada
            $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) {
            // Eliminar estos valores predeterminados podría causar problemas, así que no lo hacemos
            return array(
                'thumbnail' => $sizes['thumbnail'],
                'medium' => $sizes['medium'],
                'large' => $sizes['large']
            );
        }
28 nov 2013 17:40:30
Comentarios

Este filtro debería 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 Michaelkay
23 may 2014 20:19:51

Bien, pero ahora aún generará todas las imágenes si solo necesito un tamaño personalizado...

Gijs Gijs
10 ene 2015 21:44:23

Ocurre cuando uso objetos de imagen de Advanced Custom Fields

Gijs Gijs
10 ene 2015 22:26:14

No funciona SI add_image_size fue definido previamente con las dimensiones de la imagen que acaban de cambiar

Benjamin Intal Benjamin Intal
21 ene 2015 12:19:09

@Michaelkay este enfoque tiene una penalización de rendimiento. Cuando las imágenes se suben y luego se generan para cada tamaño, significa que el que sube es el que tiene paciencia. Este código hace que tus visitantes tengan que tener más paciencia, y Google ha demostrado que los sitios que tardan más de 2 segundos en cargar, pierden el 50% de las personas. Además, si tu sitio tiene cientos de visitas concurrentes, esto derribará tus servidores.

Tom Roggero Tom Roggero
8 mar 2019 18:01:37
1

Desafortunadamente, 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 miniaturas registrados en los metadatos de la imagen para que puedan ser considerados:

function bi_wp_calculate_image_srcset_meta($image_meta, $size_array, $image_src, $attachment_id){
    //todos los tamaños registrados
    global $_wp_additional_image_sizes;

    //algunas especificaciones del archivo fuente que usaremos mucho
    $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");

    //encontrar lo que falta
    foreach($_wp_additional_image_sizes AS $k=>$v)
    {
        if(!isset($image_meta['sizes'][$k]))
        {
            //primero, averigüemos cómo funcionaría dimensionalmente
            $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];

            //valores incorrectos
            if(!$new_h || !$new_w)
                continue;

            //generar un nombre de archivo de la misma manera que WP_Image_Editor
            $new_f = wp_basename("{$src_root}{$src_base}-{$new_w}x{$new_h}." . strtolower($src_ext));

            //finalmente, ¡agregarlo!
            $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 faltantes:

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

    //obtener información del archivo fuente
    $src_path = get_attached_file($attachment_id);
    $src_root = trailingslashit(pathinfo($src_path, PATHINFO_DIRNAME));

    //los metadatos reales de la imagen (que podrían ser alterados aquí)
    $src_meta = wp_get_attachment_metadata($attachment_id);

    //un array de tamaños posibles para buscar
    $sizes = $image_meta['sizes'];
    unset($sizes['thumbnail']);
    unset($sizes['medium']);
    unset($sizes['large']);

    $new = false;

    //recorrer las fuentes
    foreach($sources AS $k=>$v)
    {
        $name = wp_basename($v['url']);
        if(!file_exists("{$src_root}{$name}"))
        {
            //encontrar el tamaño correspondiente
            foreach($sizes AS $k2=>$v2)
            {
                //¡tenemos una coincidencia!
                if($v2['file'] === $name)
                {
                    //crearlo
                    if(!$resized = image_make_intermediate_size(
                        $src_path,
                        $v2['width'],
                        $v2['height'],
                        $v2['crop']
                    )){
                        //eliminar de las fuentes en caso de fallo
                        unset($sources[$k]);
                    }
                    else
                    {
                        //agregar la nueva miniatura a los metadatos reales
                        $new = true;
                        $src_meta['sizes'][$k2] = $resized;
                    }

                    //eliminar del array de tamaños para tener
                    //menos que buscar la próxima vez
                    unset($sizes[$k2]);
                    break;
                }//coincidencia
            }//cada tamaño
        }//cada 404
    }//cada fuente

    //si generamos algo, actualizar los metadatos del adjunto
    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);
16 abr 2016 08:08:38
Comentarios

Solo un aviso para que sepas que esto romperá el recorte manual. Me tomó horas descubrir que este era el culpable. Estoy trabajando en una solución...

Sarah Groß Sarah Groß
22 feb 2018 09:25:46
2

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

Normalmente, las miniaturas se generan cuando la imagen se sube por primera vez. Es un proceso automático, así que no tienes que preocuparte por generarlas más tarde. Piensa en ello así: si toma 1-2 segundos generar una miniatura en un servidor lento, y esperas hasta que se solicite, fuerzas 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 sube la imagen.

Al mismo tiempo, si absolutamente debes procesar las miniaturas en un momento diferente, quizás quieras echar un vistazo al plugin Viper's Regenerate Thumbnails. Utiliza una acción bajo demanda para regenerar todas tus miniaturas de imágenes... pero podrías usar un código similar para generar miniaturas solo cuando sea necesario.

26 may 2012 01:07:12
Comentarios

Creo que no entendiste el punto. Él quiere controlar para qué imágenes se necesita una miniatura. Así que algunas imágenes no necesitan ser redimensionadas en absoluto.

imrek imrek
21 mar 2015 18:55:30

La mayoría de las personas prueban las páginas cuando insertan fotos (me siento bastante seguro diciendo que todos). Esto generará los archivos necesarios una sola vez y ya está. En mi caso, tengo un tamaño de imagen de encabezado registrado. Aproximadamente 1 de cada 20 imágenes que subo son realmente para el encabezado. Así que 19 de cada 20 imágenes en mi biblioteca son un desperdicio de espacio.

JpaytonWPD JpaytonWPD
5 dic 2016 02:55:09
1

¿Existe alguna forma de activar add_image_size solo cuando sea necesario?

No exactamente. Pero puedes 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 "intermediate_image_sizes_advanced", que te permite manipular el array de tamaños justo antes de que se generen los archivos. Podrías usar este filtro cada vez que agregues una imagen de cierto "tipo", y luego eliminarlo inmediatamente después.

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

26 may 2012 01:27:07
Comentarios

tendría que añadir una opción o casilla de verificación cuando subo medios para elegir qué miniaturas quiero generar, por ejemplo. Suena bien, pero no tengo ni idea de cómo hacerlo

chifliiiii chifliiiii
26 may 2012 02:19:07
0

Puedes utilizar mi plugin (no el de Ottos) "Dynamic Image Resize" 1).

"Dynamic Image Resize" es un plugin (MU) para WordPress que ofrece un shortcode y una etiqueta de plantilla para redimensionar imágenes "al vuelo" sin necesidad de TimThumb, utilizando las funciones principales de WordPress.

El plugin incluye tanto una etiqueta de plantilla como un shortcode.

1) Acabo de enterarme del plugin de Otto. La coincidencia de nombres no fue intencional.

29 jun 2013 14:03:01
0

Puedes probar este plugin: https://wordpress.org/plugins/optimize-images-resizing

Redimensiona imágenes basándose en los tamaños de imagen registrados, pero solo cuando es necesario. También puede limpiar los tamaños de imagen existentes para que puedan regenerarse.

30 jul 2015 03:27:09
0

El plugin WP Performance Pack ofrece un "manejo mejorado de imágenes", 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, se puede desactivar el guardado de miniaturas (pero se pueden almacenar en caché y el soporte para CDN está en camino), integración con Regenerate Thumbnails (para eliminar miniaturas existentes) y algunas más.

14 may 2014 13:02:21
1

Aquí otro enfoque más: Se engancha al manejo de errores HTTP 404. Es decir, cuando la miniatura no está disponible, busca la imagen original y crea la miniatura. Ten en cuenta que esto no resuelve realmente tu problema, ya que no evita la generación de miniaturas durante la subida.

También ten en cuenta que este plugin podría ser utilizado por usuarios maliciosos para crear cualquier número de miniaturas y así agotar el espacio en tu disco.

Nota: Este plugin puede instalarse fácilmente usando Pluginception.

<?php
/*
Plugin Name: Crear miniaturas bajo demanda
Plugin URI: 
Description: Crea miniaturas en lugar de mostrar error 404. Usa en combinación con "Broken Link Checker" para crear todas las miniaturas faltantes.
Version: 0.1
Author: Jack Miller
Author URI: 
License: 
License URI: 
*/
add_filter('status_header', 'createThumbIf404');
function createThumbIf404($httpCodeString) //ej. 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);
                }
            }
        }
    }
}
//busca la imagen original dentro de $baseDir con $baseName.
//Devuelve el nombre del archivo incluyendo extensión de la imagen original o 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;
}
//Lee el archivo en $path desde el disco y lo devuelve como una petición HTTP de imagen JPG.
function ctod_sendImageAndExit($path)
{
    $fp = fopen($path, 'rb');
    header("Content-Type: image/jpeg");
    header("Content-Length: " . filesize($path));
    fpassthru($fp);
    exit();
}
22 may 2016 08:16:30
Comentarios

Me gusta esta solución. ¿Alguna vez la adaptaste para incluir más tipos de imágenes?

kalligator kalligator
8 may 2021 13:53:14
0

En otros lugares todos los tamaños creados funcionarán, pero solo en la subida de medios si deseas que se suba un tamaño específico, a continuación está el código para ello. Aquí está el enlace para más descripción - https://developer.wordpress.org/reference/hooks/wp_handle_upload_prefilter/

add_filter('wp_handle_upload_prefilter', 'custom_upload_filter' );
 
function custom_upload_filter( $file ) {
   foreach ( get_intermediate_image_sizes() as $size ) {
        if ( !in_array( $size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
            remove_image_size( $size );
        }
    }
    return $file;
}
8 dic 2020 13:11:21
0
-1

También puedes probar 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); // redimensionado
$img_src = aq_resize( $img_src, 150, 150, true); // recortado
$img_src = aq_resize( $img_src, 150, 150, null, null, true); // una imagen de 120x120 por ejemplo será escalada hasta 150x150
17 mar 2014 13:30:52