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!