Skip to content

Instantly share code, notes, and snippets.

@ctlcltd
Last active April 4, 2021 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctlcltd/ac2f44b9c3bea1f0476b7c8f8c0b1760 to your computer and use it in GitHub Desktop.
Save ctlcltd/ac2f44b9c3bea1f0476b7c8f8c0b1760 to your computer and use it in GitHub Desktop.
How to achieve the progressive loading of images with a background color in WordPress.

How to achieve the progressive loading of images with a background color in WordPress

To achieve the progressive loading of images, a background color can be used, which can be assigned before loading is performed and it will be shown during the loading phase of the web page. It could be an average of the image color, the predominant color, the same background color of the image, a background image or a color you like. This is an example of how to integrate it into an existing WordPress theme with filters. It is also possible to alter the IPTC metadata of the uploaded image and magically put a color value to the attachment metadata.

I used "wp_read_image_metadata" and "wp_generate_attachment_metadata" hooks to add a color value with the IPTC Instructions field and save a post metadata of the attachment.

/**
 * IPTC metadata - Instructions
 *
 * @see wp_read_image_metadata()
 *
 * @param array $meta
 * @param string $file
 * @param int $image_type
 * @param array $iptc
 * @return array $meta
 */
function image_add_meta_iptc_instructions( $meta, $file, $image_type, $iptc ) {
	if ( ! empty( $iptc['2#040'][0] ) ) {
		$meta['instructions'] = trim( $iptc['2#040'][0] );
	}

	return $meta;
}

add_filter( 'wp_read_image_metadata', 'image_add_meta_iptc_instructions', 10, 4 );

Here is a post metadata of the attachment that is inserted so it is not necessary to handle the image metadata directly, this is what already happens with the alternative text, for example. I used a single filter for "wp_generate_attachment_metadata" instead of filtering each API.

/**
 * Custom image metadata - background color dominance
 *
 * @see wp_generate_attachment_metadata()
 *
 * @param array $metadata
 * @param int $attachment_id
 * @return array $metadata
 */
function image_add_meta_bg_dominance( $metadata, $attachment_id ) {
	if ( isset( $metadata['image_meta']['instructions'] ) ) {
		if (
			preg_match(
				'/backgroundColorDominance: (#([a-fA-F0-9]{3}){1,2}\b)/i',
				$metadata['image_meta']['instructions'],
				$img_bg_dominance
			)
		) {
			update_post_meta(
				$attachment_id,
				'_image_bg_dominance',
				strtolower( $img_bg_dominance[1] )
			);
		}
	}

	return $metadata;
}

add_filter( 'wp_generate_attachment_metadata', 'image_add_meta_bg_dominance', 10, 2 );

Finally, a style attribute is added for the background color of the images. Can be hooked "wp_get_attachment_image_attributes" and should work with almost any existing theme.

/**
 * Add the custom attribute for background color dominance to images
 *
 * @see wp_get_attachment_image()
 *
 * @param array $attr
 * @param WP_Post $attachment
 * @return array $attr
 */
function attachment_image_attr_style_bg_dominance( $attr, $attachment ) {
	$attachment_id = $attachment->ID;

	if ( $img_bg_dominance = get_post_meta( $attachment_id, '_image_bg_dominance', true ) ) {
		if ( empty( $attr['style'] ) )
			$attr['style'] = '';
		else
			$attr['style'] .= ' ';

		$attr['style'] .= "background-color: {$img_bg_dominance};";
	}

	return $attr;
}

add_filter( 'wp_get_attachment_image_attributes', 'attachment_image_attr_style_bg_dominance', 10, 2 );

 

There are also other methods to show a preview before the loading of images, without leaving gaps when loading. One of the many, using low quality image placeholders (lqip), details in this old gist: https://gist.github.com/ctlcltd/1fd7a58722c4e4351073.

<?php
/**
* IPTC metadata - Instructions
*
* @see wp_read_image_metadata()
*
* @param array $meta
* @param string $file
* @param int $image_type
* @param array $iptc
* @return array $meta
*/
function image_add_meta_iptc_instructions( $meta, $file, $image_type, $iptc ) {
if ( ! empty( $iptc['2#040'][0] ) ) {
$meta['instructions'] = trim( $iptc['2#040'][0] );
}
return $meta;
}
add_filter( 'wp_read_image_metadata', 'image_add_meta_iptc_instructions', 10, 4 );
/**
* Custom image metadata - background color dominance
*
* @see wp_generate_attachment_metadata()
*
* @param array $metadata
* @param int $attachment_id
* @return array $metadata
*/
function image_add_meta_bg_dominance( $metadata, $attachment_id ) {
if ( isset( $metadata['image_meta']['instructions'] ) ) {
if (
preg_match(
'/backgroundColorDominance: (#([a-fA-F0-9]{3}){1,2}\b)/i',
$metadata['image_meta']['instructions'],
$img_bg_dominance
)
) {
update_post_meta(
$attachment_id,
'_image_bg_dominance',
strtolower( $img_bg_dominance[1] )
);
}
}
return $metadata;
}
add_filter( 'wp_generate_attachment_metadata', 'image_add_meta_bg_dominance', 10, 2 );
/**
* Add the custom attribute for background color dominance to images
*
* @see wp_get_attachment_image()
*
* @param array $attr
* @param WP_Post $attachment
* @return array $attr
*/
function attachment_image_attr_style_bg_dominance( $attr, $attachment ) {
$attachment_id = $attachment->ID;
if ( $img_bg_dominance = get_post_meta( $attachment_id, '_image_bg_dominance', true ) ) {
if ( empty( $attr['style'] ) )
$attr['style'] = '';
else
$attr['style'] .= ' ';
$attr['style'] .= "background-color: {$img_bg_dominance};";
}
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'attachment_image_attr_style_bg_dominance', 10, 2 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment