Wie erstelle ich Thumbnails, wenn ich sie benötige?

18

Ich habe 1000 Bilder. Wie kann ich WordPress dazu bringen, nur bei Bedarf einen Daumen zu generieren? Zum Beispiel verwendet der Home Slider nur 10 Bilder. Ich möchte nicht, dass die anderen 1000 Bilder dieses Vorschaubild als Verschwendung von Platz und Ressourcen erzeugen.

Gibt es eine Möglichkeit, add_image_size nur bei Bedarf auszulösen?

Vielen Dank

UPDATE Wie Sie bereits erwähnt haben, ist add_image_size nicht wirklich das, was abgefeuert werden muss. Was es großartig wäre, ist, die Bildgröße zu ändern, wenn ich das_post_thumbnail ('Slider-Thumb') benutze; Vielleicht verlangsamt dies die erste Ansicht des Bildes, aber diese Ansicht wird normalerweise von mir generiert, wenn ich den Beitrag tatsächlich überprüfe, damit es mich nicht interessiert.

Also zwischen meinen Beiträgen, Slider, Blog-Thumbnauls, Portfolio-Thumbnails usw. habe ich 1000 Bilder und ich möchte, dass nur 10 Bilder für den Slider angepasst werden. Ich sehe eine Menge verschwendeter Ressourcen, um die Thumbnail-Größe für die anderen 990 Bilder zu generieren.

Hoffe es ist jetzt klar, sorry für mein Englisch

chifliiiii
quelle
2
Wie werden aus den zusätzlichen 990 Bildern Miniaturansichten erzeugt, die mehr Platz und Ressourcen verschwenden als ungenutzte 990 Bilder? Wäre es nicht sinnvoller, nur die Bilder hochzuladen, die Sie aktiv verwenden?
SickHippie
Auch wenn kompetentere Programmierer stichhaltige Argumente gegen Ihre Idee vorbringen, finde ich sie interessant. Ich habe einige Plugins und Themes gesehen, die Bilder hochladen, ohne Daumen zu generieren (nicht sicher, welche gerade). Aber mein großer Zweifel an Ihrer Frage ist: Wann brauchen Sie das? . Was wird der Filter sein?
Brasofilo
1
Du hast mich falsch verstanden. Ich verwende die 990 Bilder in Beiträgen, ich verwende nur nicht die im Home Slider. Einige von ihnen brauche ich Daumen für das Portfolio, andere für Blog-Daumen, etc.
Chifliiiii

Antworten:

12

Schauen Sie sich das Dynamic Image Resizer-Plugin von Otto an

Dieses Plugin ändert die Art und Weise, wie WordPress Bilder erstellt, damit diese nur dann erzeugt werden, wenn sie tatsächlich irgendwo im laufenden Betrieb verwendet werden. Auf diese Weise erstellte Bilder werden in den normalen Upload-Verzeichnissen gespeichert, um später vom Webserver schnell gesendet zu werden. Das Ergebnis ist, dass Speicherplatz gespart wird (da Bilder nur bei Bedarf erstellt werden) und das Hochladen von Bildern viel schneller erfolgt (da die Bilder beim Hochladen nicht mehr generiert werden).

Chris_O
quelle
2
Beachten Sie, dass dieses Plugin ein Problem beim Hinzufügen von Bildern zu alten Posts hat. Patches willkommen.
Otto
Das ist genau das, wonach ich gesucht habe. Ich werde es versuchen. Funktioniert es also nur bei neuen Posts?
Chifliiiii
1
Für diejenigen, die jetzt auf diesen Beitrag stoßen, ist hier ein ähnliches Plugin, das offenbar aktiv entwickelt wird: wordpress.org/plugins/fly-dynamic-image-resizer
Tim Malone
7

Fügen Sie dies in Ihre Theme-Funktionsdatei ein. Es verhindert, dass Wordpress beim Hochladen etwas anderes als die 3 Standardgrößen erstellt.

Wenn dann ein Bild in einer bestimmten Größe angefordert wird, die noch nicht generiert wurde, wird es nur einmal erstellt.

        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']
            );
        }
Patrick
quelle
Dieser Filer sollte Standard in WordPress sein. Warum für jedes Bild jede Größe erzeugen? Ich füge diesen Code meinen benutzerdefinierten Designs hinzu. Danke
Michaelkay
2
Schön, aber jetzt werden immer noch alle Bilder generiert, wenn ich nur eine benutzerdefinierte Größe brauche.
Gijs
Es passiert, wenn ich Bildobjekte aus erweiterten benutzerdefinierten Feldern verwende
Gijs
Funktioniert nicht, WENN add_image_size zuvor mit den gerade geänderten Bildabmessungen definiert wurde
Benjamin Intal
@Michaelkay es gibt eine Leistungsstrafe in diesem Ansatz. Wenn Bilder hochgeladen und dann für jede Größe generiert werden, bedeutet dies, dass der Uploader derjenige ist, der Geduld hat. Mit diesem Code müssen Ihre Besucher mehr Geduld haben. Google hat bewiesen, dass das Laden von Websites, die länger als zwei Sekunden dauern, 50% der Nutzer zum Erliegen bringt. Auch wenn Ihre Site Hunderte von gleichzeitigen Besuchen aufweist, werden Ihre Server heruntergefahren.
Tom Roggero
2

Leider bricht die Antwort von @ Patrick die in WP 4.4 eingeführten srcset-Funktionen. Zum Glück müssen wir nur zwei zusätzliche Funktionen hinzufügen!

Zunächst müssen wir alle registrierten Miniaturbildgrößen vorübergehend wieder in die Bildmetadaten einfügen, damit sie berücksichtigt werden können:

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

Dann müssen wir die Matches durchgehen und fehlende Thumbnails generieren:

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
quelle
Nur ein Heads-Up, um Ihnen mitzuteilen, dass dies zu einem Bruch mit dem harten Beschneiden führen wird! Ich habe Stunden gebraucht, um herauszufinden, dass dies der Schuldige war. Ich arbeite an einer Lösung ...
Constantin Groß
1

Eigentlich add_image_size()nicht die Vorschau erzeugt, registriert er nur eine Bildgröße wie bei Wordpress verfügbar.

In der Regel werden beim ersten Hochladen des Bildes Miniaturansichten erstellt. Es ist ein automatischer Prozess, sodass Sie sich später nicht mehr darum kümmern müssen, sie zu generieren. Stellen Sie sich das so vor: Wenn die Erstellung eines Thumbnails auf einem langsamen Server 1 bis 2 Sekunden dauert und Sie warten, bis es angefordert wird, zwingen Sie den Anfragenden, weitere 1 bis 2 Sekunden pro Bild zu warten , um den Inhalt anzuzeigen . Es ist viel einfacher, dies im Voraus zu tun - dh wenn das Bild hochgeladen wird.

Wenn Sie die Miniaturansichten unbedingt zu einem anderen Zeitpunkt verarbeiten müssen, sollten Sie sich gleichzeitig das Plug-in "Miniaturansichten neu generieren" von Viper ansehen . Mit einer On-Demand-Aktion werden alle Miniaturansichten Ihrer Bilder neu generiert. Sie können jedoch ähnlichen Code verwenden, um Miniaturansichten nur bei Bedarf zu generieren.

EAMann
quelle
Ich denke, du hast den Punkt nicht verstanden. Er möchte steuern, für welche Bilder ein Vorschaubild benötigt wird. Einige Bilder müssen also überhaupt nicht in der Größe verändert werden.
Betrunkener Meister
Die meisten Leute testen Seiten, wenn die Fotos eingefügt werden (ich fühle mich ziemlich sicher, wenn ich alle sage). In meinem Fall habe ich eine Header-Bildgröße registriert. Ungefähr 1 von 20 Bildern, die ich hochlade, sind eigentlich für den Header. 19 von 20 Bildern in meiner Bibliothek sind also Platzverschwendung.
JpaytonWPD
1

Gibt es eine Möglichkeit, add_image_size nur bei Bedarf auszulösen?

Nicht genau. Sie können die Liste der registrierten Größen jedoch filtern, bevor die Miniaturansichten generiert werden. Die Funktion wp_generate_attachment_metadata () (die die Funktion aufruft, die die Miniaturbilder generiert) verfügt über einen Filter mit dem Namen "intermediate_image_sizes_advanced", mit dem Sie das Array der Größen unmittelbar vor dem Generieren der Dateien bearbeiten können. Sie können diesen Filter verwenden, wenn Sie ein Bild eines bestimmten "Typs" hinzufügen und es anschließend sofort entfernen.

Ich denke, Ihre größte Herausforderung wäre es, herauszufinden, wie Sie zwischen Bildern, für die zusätzliche Größen erforderlich sind, und solchen, für die dies nicht der Fall ist, unterscheiden können.

MathSmath
quelle
Ich müsste eine Option oder ein Kontrollkästchen hinzufügen, wenn ich Medien hochlade, um auszuwählen, welche Thumbs ich zum Beispiel generieren möchte. Klingt gut, aber ich habe keine Ahnung, wie das geht
chifliiiii
1

Sie können mein (nicht Ottos ) Plugin "Dynamic Image Resize" 1) verwenden .

"Dynamic Image Resize" ist ein WordPress (MU-) Plugin, das einen Shortcode und ein Template-Tag bietet, um die Größe von Bildern "on the flight" ohne TimThumb, aber mit WP-Kernfunktionen zu ändern.

Das Plugin wird mit einem Template-Tag und einem Shortcode geliefert .

1) Habe gerade von Ottos Plugin erfahren. Namenskollision war nicht vorgesehen.

Kaiser
quelle
1

Sie können dieses Plugin ausprobieren: https://wordpress.org/plugins/optimize-images-resizing

Die Größe der Bilder wird basierend auf Ihrer registrierten Bildgröße geändert, jedoch nur bei Bedarf. Kann auch vorhandene Bildgrößen bereinigen, damit sie neu generiert werden können.

user2128576
quelle
0

Das WP Performance Pack Plugin bietet "verbessertes Bildhandling", das auf Ottos Dynamic Image Resizer basiert, aber viele Verbesserungen beinhaltet, zB: Erstens ist es kompatibel mit der neuesten WordPress-Version (3.9.1), verwendet WP_Image_Editor und kann Thumbnails speichern ausgeschaltet sein (aber sie können zwischengespeichert werden und der CDN-Support ist in Arbeit), die Integration von Thumbnails neu generieren (um vorhandene Thumbnails zu löschen) und vieles mehr.

Björn
quelle
-1

Sie können auch Aqua Resizer ausprobieren - https://github.com/syamilmj/Aqua-Resizer/

Es ist nur eine Datei.

Du kannst es so benutzen:

$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
quelle
-1

Hier noch ein anderer Ansatz: Seine Haken in der 404-HTTP-Fehlerbehandlung. Wenn die Miniaturansicht nicht verfügbar ist, suchen Sie das Originalbild und erstellen Sie die Miniaturansicht. Beachten Sie, dass dies Ihr Problem nicht wirklich löst, da es die Erstellung von Miniaturansichten während des Uploads nicht verhindert.

Beachten Sie auch, dass dieses Plugin möglicherweise von böswilligen Benutzern verwendet wird, um eine beliebige Anzahl von Miniaturansichten zu erstellen und damit Ihren Speicherplatz zu erschöpfen.

Hinweis: Dieses Plugin kann einfach mit Pluginception installiert werden .

<?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
quelle