Skip to content

How-to Guides

Technical References

Strip image metadata on upload

Image metadata is not stripped from uploaded images by default, so this is left to code within applications.

Below is an example implementation that will strip images on upload. Using this approach avoids the need to strip metadata from images when being displayed.

Add the following to a theme’s functions.php, or to a separate plugin:

add_filter( 'wp_handle_upload', 'yourprefix_strip_metadata_from_images_on_upload' );
/**
 * Overwrite the uploaded image with a new version that has no metadata.
 *
 * @param array $upload {
 *     Upload arguments.
 *
 *     @type string $file The path to the image file.
 *     @type string $url  The URL to the image.
 *     @type string $type The MIME type of the image.
 * }
 * @return array Unmodified $upload array.
 */
function yourprefix_strip_metadata_from_images_on_upload( array $upload ):array {
	// Return if the file is not an image.
	if ( ! in_array( $upload['type'], array( 'image/jpeg', 'image/png', 'image/gif' ), true ) ) {
		return $upload;
	}

	try {
		yourprefix_strip_metadata_from_image( $upload['file'] );
	} catch ( \GmagickException $e ) {
		// Do nothing.
	}

	return $upload;
}

/**
 * Strip metadata from an image file, but keep the ICC color profile data.
 *
 * @param string      $file   Path to the image file.
 * @param string|null $output Path to write the image to. Leave null to overwrite the original.
 */
function yourprefix_strip_metadata_from_image( string $file, ?string $output = null ) {
	$image = new \Gmagick( $file );

	// Check if we have an ICC profile, so we can restore it later.
	try {
		$profile = $image->getimageprofile( 'icc' );
	} catch ( \GmagickException $exception ) {
		// Raises an exception if no profile is found.
	}

	// Strip all image metadata.
	$image->stripimage();

	// Restore the ICC profile if we have one.
	if ( ! empty( $profile ) ) {
		$image->setimageprofile( 'icc', $profile );
	}

	// Replace the uploaded image with the stripped down version.
	if ( empty( $output ) ) {
		$output = $file;
	}

	$image->writeimage( $output, true );
	$image->destroy();
}

Last updated: November 27, 2020