Skip to content

Instantly share code, notes, and snippets.

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 SimonFricker/ae26703a191b3d8ce5d20dce60b55e3a to your computer and use it in GitHub Desktop.
Save SimonFricker/ae26703a191b3d8ce5d20dce60b55e3a to your computer and use it in GitHub Desktop.
How to easily generate low quality image placeholders (lqip) in WordPress

#How to easily generate low quality image placeholders (lqip) in WordPress

I have made this function using the WP_Image_Editor class and I have filtered through the "wp_generate_attachment_metadata" hook. You can modify the "theme" namespace into function names with your theme name or in anyway you like.

Applying the filter directly to wp_generate_attachment_metadata the image placeholders are auto added into WordPress metadata, so when your add/modify/delete an image (or regenerate it via a plugin), it accomplishes to modify also to the image placeholders.

The use of the native theme support can prevent the generation of lqip or target specific image sizes to generate.

It contains an hook filter lqip_quality to modify the quality without have to modify the function.

This function could be modified and extended for example to differentiate quality for each size or apply filtering to a specific image size, etc.

##Theme initialization

/**
 * Your theme setup
 */
function theme_setup() {
	// if you want to generate lqip for all the image sizes
	add_theme_support( 'lqip' );

	// if you want to specify what image sizes to generate lqip
	add_theme_support( 'lqip', array( 'thumbnail', 'medium' ) );
}
add_action( 'after_theme_setup', 'theme_setup' );

##My simple function to make lqip

/**
 * Easy adds lqip to WordPress
 * 
 * @global array $_wp_theme_features
 * @global array $_wp_additional_image_sizes
 * @param array $metadata
 * @param int $attachment_id
 * @return array $metadata
 */
function theme_lqip_support( $metadata, $attachment_id ) {
	global $_wp_theme_features;

	if ( ! isset( $_wp_theme_features['lqip'] ) )
		return $metadata;

	global $_wp_additional_image_sizes;

	if ( is_array( $_wp_theme_features['lqip'] ) ) {
		$image_sizes = $_wp_theme_features['lqip'][0];
	} else {
		$image_sizes = get_intermediate_image_sizes();
		$image_sizes = apply_filters( 'intermediate_image_sizes_advanced', $image_sizes );
	}

	$file = get_attached_file( $attachment_id );
	$quality = apply_filters( 'lqip_quality', 10 );

	if (
		preg_match( '!^image/!', get_post_mime_type( $attachment_id ) ) &&
		file_is_displayable_image( $file )
	) {
		$path_parts = pathinfo( $file );

		foreach ( $image_sizes as $size ) {
			if ( isset( $metadata['sizes'][$size] ) ) {
				if ( isset( $_wp_additional_image_sizes[$size]['width'] ) )
					$width = intval( $_wp_additional_image_sizes[$size]['width'] );
				else
					$width = get_option( "{$size}_size_w" );

				if ( isset( $_wp_additional_image_sizes[$size]['height'] ) )
					$height = intval( $_wp_additional_image_sizes[$size]['height'] );
				else
					$height = get_option( "{$size}_size_h" );

				if ( isset( $_wp_additional_image_sizes[$size]['crop'] ) )
					$crop = intval( $_wp_additional_image_sizes[$size]['crop'] );
				else
					$crop = get_option( "{$size}_crop" );

				$new_size = $size . '-lqip';
				$filename = str_replace(
					'.' . $path_parts['extension'],
					'-lqip.' . $path_parts['extension'],
					$metadata['sizes'][$size]['file']
				);
				
				$image = wp_get_image_editor( $file );
				$image->resize( $width, $height, $crop );
				$image->set_quality( $quality );
				$image->save( $path_parts['dirname'] . '/' . $filename );

				if ( ! is_wp_error( $image ) ) {
					$metadata['sizes'][$new_size] = $metadata['sizes'][$size];
					$metadata['sizes'][$new_size]['file'] = $filename;
				}
			}
		}
	}

	return $metadata;
}
add_filter( 'wp_generate_attachment_metadata', 'theme_lqip_support', 10, 2 );

Debug

To debug the filter during image upload or manipulation you can add this code in the function theme_lqip_support before the return or inside the foreach loop.

A fresh dump.txt file will be created in the same directory files where stored.

	file_put_contents( $path_parts['dirname'] . '/dump.txt', print_r(
		array(
			'_wp_theme_features' => $_wp_theme_features,
			'_wp_additional_image_sizes' => $_wp_additional_image_sizes,
			'image_sizes' => $image_sizes,
			'metadata' => $metadata,
			'attachment_id' => $attachment_id,
			'file' => $file,
			'quality' => $quality,
			'path_parts' => $path_parts,
			'image' => $image,
			'new_size' => $new_size,
			'filename' => $filename
		)
	, true ) );

Feedbacks and suggestions will be appreciated :)

Tested up to: WordPress 4.0 License: MIT MIT License (Expat)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment