Unscharfe Beitragsbilder nachschärfen

WordPress erzeugt zu jedem Bild, das man hochlädt, eine kleine Serie von verkleinerten Versionen. Das ist sehr praktisch, weil man dadurch jedes Bild in verschiedenen Größen zur Hand hat. Das spart Ladezeit.

Nun war mir in letzter Zeit aufgefallen, dass die heruntergerechneten Bild-Varianten im Vergleich zum Originalbild unscharf aussehen. Ich hatte zuerst den Verdacht, dass der Unschärfe-Effekt durch eine Skalierung im Browser (CSS) entsteht.

Aber bei den Projekten, bei denen mir die Unschärfe aufgefallen war, war keine Verkleinerung per Browser im Spiel. Das verkleinerte Bild war einfach ein Stück unschärfer als das Originalbild (das selbstverständlich ordentlich scharf war).

Im Nachhinein wundere ich mich, dass mir das nicht schon früher aufgefallen ist. Denn der Unschärfe-Effekt ist ein bekanntes Phänomen, das jeder kennt, der schon Mal mit einem Bildbearbeitungs-Programm wie Photoshop gearbeitet hat. Verkleinert man ein Bild, verliert es an Schärfe. In der Bildbearbeitung gehört das Nachschärfen daher zur Routine.

Beitragsbilder schärfer machen

Man könnte jetzt alle Bilder der Reihe nach mit Photoshop öffnen und mit dem „Unscharf Maskieren“-Filter behandeln. Das ist aber nicht so richtig praktisch und nachhaltig ist es auch nicht.

Bei den WordPress Plugins gibt es ein paar, die sich des Themas annehmen. Leider konnte ich keines davon zum Laufen bringen. Die einfacheren wollten nicht funktionierten (sind durchweg schon etwas älter) und die ImageMagick-Maschinerie war mir einen Tick zu wuchtig.

Ich habe dann noch – mehr der Vollständigkeit halber – ausprobiert, ob es etwas hilft, wenn ich die JPG-Kompressionsrate auf 100% setze. Aber das hat nichts bewirkt, die Unschärfe bleibt.

add_filter( 'jpeg_quality', create_function( '', 'return 100;' ) );

Irgendwann bin ich dann auf diesen Code aufmerksam geworden. (Die Funktion wp_load_images habe ich ersetzt, s. Updatenotiz unten).

function ks_sharpen_resized_files( $resized_file ) {

    $image = imagecreatefromstring( file_get_contents( $resized_file ) );

    if ( !is_resource( $image ) )
        return new WP_Error( 'error_loading_image', $image, $file );

    $size = @getimagesize( $resized_file );
    if ( !$size )
        return new WP_Error('invalid_image', __('Could not read image size'), $file);
    list($orig_w, $orig_h, $orig_type) = $size;

    switch ( $orig_type ) {
        case IMAGETYPE_JPEG:
            $matrix = array(
                array(-1, -1, -1),
                array(-1, 16, -1),
                array(-1, -1, -1),
            );

            $divisor = array_sum(array_map('array_sum', $matrix));
            $offset = 0; 
            imageconvolution($image, $matrix, $divisor, $offset);
            imagejpeg($image, $resized_file,apply_filters( 'jpeg_quality', 90, 'edit_image' ));
            break;
        case IMAGETYPE_PNG:
            return $resized_file;
        case IMAGETYPE_GIF:
            return $resized_file;
    }

    return $resized_file;
}   

add_filter('image_make_intermediate_size', 'ks_sharpen_resized_files',900);

Ich konnte zuerst gar nicht glauben, dass der Code das tut was ich brauche. Aber hier ist höhere PHP-Magie am Werk und es funktioniert!
Wenn ich jetzt ein neues Bild hochlade, werden alle verkleinerten Bildvarianten leicht nachgeschärft.

DEMO

400px Variante ohne Bearbeitung | pexels.com

Dasselbe Bild, diesmal nachgeschärft

Kleine Einschränkung: Die Bilder müssen im JPG-Format vorliegen, sonst greift das Script nicht.

Tipp

Ist das PHP-Script aktiv und man lässt das Plugin Regenerate Thumbnails durchlaufen, dann werden alle verkleinerten Beitragsbilder nachgeschärft.

Aber Achtung: Beim nächsten Durchlauf von Regenerate Thumbnails würde dasselbe wieder passieren. Die Bilder würden noch einmal geschärft! .

Also: Falls ihr Regenerate Thumbnails mehrmals verwenden wollt, müsstest ihr das Script vorher auskommentieren bzw. in ein Plugin auslagern, das ihr bei Bedarf deaktivieren könnt. Sonst macht ihr euch die Bilder kaputt.

Update 17.8.2017
ENTWARNUNG. Hier hatte ich einen Denkfehler gemacht. Regenerate Thumbnails geht immer vom Originalbild aus, das bedeutet, dass die verkleinerten Varianten bei jedem Durchgang neu erzeugt werden. Das heisst also, die kleinen Bilder werden nur einmal geschärft und nicht mehrmals.

Update 19.89.2017
Roman hat mich in den Kommentaren darauf hingewiesen, dass die Funktion wp_load_images veraltet ist. Ich habe deshalb die 2. Zeile in der Funktion oben ersetzt durch seinen Vorschlag. Vielen Dank, Roman!

Hat Dir der Artikel weitergeholfen?

Kommentare, die nichts mit dem jeweiligen Artikel zu tun haben, oder die (weitgehend) inhaltslos sind und keinen Mehrwert für andere Leserinnen und Leser bieten, veröffentlichen wir nicht.

12 Kommentare zu “Unscharfe Beitragsbilder nachschärfen

  • Hallo,

    interessanter Artikel. Allerdings sehe ich keinen Unterschied bei dem Hundefoto und ich schaue mir es auf dem iPad mit Retina Display an.

    • Hallo, Björn!
      Ja, auf dem iPad ist der Unterschied kaum zu sehen. Aber es gibt einen Unterschied, wenn auch sehr klein. Auf dem Desktop-Rechner ist es deutlicher (die Schnurrhaare!). Ich habe viele Jahre mit Bildbearbeitung zugebracht, das hat mich wohl geprägt. Mir gefallen die Bilder mit weniger Unschärfe besser.

      Schöne Grüße von Kirsten

      • Hallo Kirsten,

        cooler Tipp. Werde es gleich in meinem WordPress-Newsletter aufnehmen.

        Der Unterschied ist zwar nur leicht, aber dennoch bemerkbar.

      • Ja, der Unterschied ist wahrscheinlich was für Nerds! ;o)

  • Hallo Kirsten,

    die „Magie“ passiert in der Zeile, in welcher die imageconvolution (Faltungsmatrix) Funktion der php Erweiterung GD ausgeführt wird. Die Matrix berechnet die Pixel deines Bildes anhand der Parameter aus dem $matrix Array neu, so dass es in deinem Fall schärfer dargestellt wird.

    Wenn du in Photoshop oder Gimp ein Bild unscharf maskierst, hast du im Grunde genommen nur eine für Menschen optimierte Oberfläche mit Reglern vor dir, über die ähnlich komplexen Anordnung von Zahlenwerten generiert und auf das Bild angewandt werden.

    Höhere Mathemagie trifft es wohl am besten ;-)

    LG
    Marvin

    • Hallo, Marvin,
      Danke für den Hinweis. Dass da derselbe Mechanismus am Werk ist wie beim Unscharf Maskieren, hatte mir so zusammengereimt. Die Mathematik dahinter begreife ich allerdings nicht wirklich ;o)

      Schöne Grüße

      Kirsten

  • Stimmt, am Desktop-PC und einem großen Monitor fällt der Unterschied immens auf, wow! Danke für den Tipp, baue ich mir auch ein!

  • Hallo,

    danke für den tollen Tipp! Ich hatte mich auch immer ein bisschen gewundert, dass die Bilder nicht so ganz optimal sind, dachte aber, dass das eben so ist und hatte auch nur mit der JPG-Kompressionsrate probiert, das etwas zu verbessern.
    Jetzt weiß ich es besser :-)
    Beste Grüße
    Susanne

  • Liebe Kirsten,

    vielen Dank für den Artikel!

    Da die Funktion ‚wp_load_image()‘ aber deprecated ist, sollte die erste Zeile der Funktion vielleicht besser wie folgt aussehen:

    $image = imagecreatefromstring( file_get_contents( $resized_file ) );

    Beste Grüße,
    Roman

    • Hallo, Roman,
      vielen Dank für den Hinweis! Das hatte ich tatsächlich übersehen. Dann werde ich den Code mal anpassen – ich wollte sowieso nochmal drüber gehen.

      Schöne Grüße

      Kirsten

  • Olaf Müller 10. Oktober 2017

    Danke für den spannenden Beitrag, ich bin beruflich Web-/Grafik-Designer und immer bemüht um einen Ausgleich aus Schärfe und Grösse (Kilobyte), da sich beides oftmals beisst. Dein Resultat sieht echt um etliches besser aus, gefällt mir. Wie ist das mit der Grösse vorher/nachher? Und wie verträgt sich das mit Image Optimizer Plugins?

    • Hallo, Olaf,

      auf die Größe hat das Schärfen keinen Einfluss. Das ist wie bei Photoshop auch, die Bildgröße bleibt gleich.
      Wie sich die Methode mit Plugins verträgt müsste man testen. Welche Plugins hat du da im Auge, was machen die?

      Kirsten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.