Veröffentlicht am Schreib einen Kommentar

Pfade von Bildern aus der Mediathek nach dem Upload

Um Bilder direkt nach dem Upload in die Mediathek weiterverarbeiten zu können, musste ich an deren Pfad kommen. Aber nicht nur an die des Originalbildes, sondern auch an die aller Thumbnails. Selbige werden innerhalb von wp_generate_attachment_metadata() generiert und stehen erst ab diesem Zeitpunkt zur Verfügung.

Allerdings nicht, wie man sich denken könnte, einfach über die Metadaten des Bildes, die als Post-Metadaten abgelegt werden. Dann deren Aktualisierung findet erst danach statt – und zwar für jede Bildgröße einzeln. Daher funktioniert hier auch ein Hook auf updated_postmeta nicht sauber, da dieser für jede Bildgröße gefeuert wird und man nicht weiß, ob nach dem aktuellen Durchlauf noch ein Durchlauf mit einer weiteren Bildgröße ausgeführt wird oder nicht.

Der einfache Teil

Für das hochgeladene Bild selbst in der vollen Auflösung (oder in der entsprechend skalierten bei zu großen Bildern) gibt es mit get_attached_file( $attachment_id ) direkt eine Funktion, die den Pfad des Bildes zurückgibt.

Natürlich könnte man diesen Bildpfad parsen und daraus die weiteren Bildgrößen versuchen zu erkennen. Das war mir jedoch zu fehleranfällig.

Hook nach der Generierung aller Thumbnails

Glücklicherweise gibt es innerhalb von wp_generate_attachment_metadata() auch einen gleichnamigen Hook, der dann ausgeführt wird, nachdem alle Bildgrößen generiert wurden. Informationen über die Bilddaten finden sich dann in den Metadaten, die zu diesem Zeitpunkt noch nicht in die Datenbank geschrieben wurden, aber über den Hook zurückgegeben werden.

Anhand von get_intermediate_image_sizes() kann ich mir dann noch alle Bildgrößen ausgeben lassen, die maximal generiert wurden und anhand der Metadaten prüfen, ob diese vorhanden sind.

Spezialfall „scaled“

Überschreitet ein Bild eine bestimmte Auflösung, kann es sein, dass es automatisch beim Speichern in der Mediathek herunterskaliert wird. Erkennbar ist das neben der veränderten Auflösung auch am Dateinamen, der am Ende ein -scaled besitzt (an derselben Stelle, an der auch die Größen der generierten Thumbnails erkennbar sind (beispielsweise bei -150x150). (Dieses Verhalten kann man mit dem Filter add_filter( 'big_image_size_threshold', '__return_false' ); deaktivieren.)

Warum ich das erwähne? In meinem Fall musste ich sichergehen, dass ich vom richtigen Originalbild ausgehe und nicht von einem bereits von WordPress verarbeiteten Bild. Deshalb habe ich das in meinem nachfolgenden Code mit beachtet.

Der Code

Beachtet man all diese Dinge, kann der Code am Ende folgendermaßen aussehen:

/**
 * Copy all metadata from the original file to all resized images.
 * 
 * @param	array	$metadata Array of attachment meta data
 * @param	int		$attachment_id Current attachment ID
 * @return	array Array of attachment meta data
 */
function add_metadata_to_attachment_thumbnails( array $metadata, $attachment_id ): array {
	$base_image = get_attached_file( $attachment_id );
	$filetype = wp_check_filetype( $base_image );
	
	if ( $filetype['type'] !== 'image/jpeg' ) {
		return $metadata;
	}
	
	$images = [];
	$path = dirname( $base_image );
	$sizes = get_intermediate_image_sizes();
	
	if ( strpos( $base_image, '-scaled' ) !== false ) {
		// add scaled image size as well
		$metadata['sizes']['scaled'] = [
			'file' => basename( $base_image ),
		];
		$sizes[] = 'scaled';
		// remove '-scaled' to get the real original image
		$base_image = str_replace( '-scaled', '', $base_image );
	}
	
	// get path for each image size
	foreach ( $sizes as $size ) {
		if ( empty( $metadata['sizes'][ $size ]['file'] ) ) {
			continue;
		}
		
		$images[ $size ] = $path . DIRECTORY_SEPARATOR . $metadata['sizes'][ $size ]['file'];
	}
	
	foreach ( $images as $image ) {
		// do something
	}
	
	// remove custom image size
	unset( $metadata['sizes']['scaled'] );
	
	return $metadata;
}

add_action( 'wp_generate_attachment_metadata', 'add_metadata_to_attachment_thumbnails', 10, 2 );

Ich habe zusätzlich noch in Zeile 10–14 eine Prüfung eingebaut, damit in meinem Fall nur JPG-Bilder verarbeitet werden.

In Zeile 40 kann dann angegeben werden, was man mit den Bildern tun möchte.

Schreibe einen Kommentar

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