Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save maxyudin/5ed1699f15aa04f0aff59c1225e41a1e to your computer and use it in GitHub Desktop.
Save maxyudin/5ed1699f15aa04f0aff59c1225e41a1e 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_setup_theme', '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