mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-07-01 15:50:09 +00:00
Media: Adjust PDF upload handling to remove non-opaque alpha channels from previews.
Previously, Imagick uploads of PDF files with non-opaque alpha channels would result in a black background replacing alpha in the generated thumbnail. This patch adds a `remove_pdf_alpha_channel()` function in the Imagick classes to use a white background instead. Props gitlost, joemcgill, joedolson, launchinteractive, emirpprime, mwtsn, ceer, maysi, madejackson, 6adminit, costdev, oglekler. Fixes #39216. git-svn-id: https://develop.svn.wordpress.org/trunk@56271 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -168,6 +168,10 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor {
|
||||
$this->image->setIteratorIndex( 0 );
|
||||
}
|
||||
|
||||
if ( 'pdf' === $file_extension ) {
|
||||
$this->remove_pdf_alpha_channel();
|
||||
}
|
||||
|
||||
$this->mime_type = $this->get_mime_type( $this->image->getImageFormat() );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'invalid_image', $e->getMessage(), $this->file );
|
||||
@@ -751,6 +755,24 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor {
|
||||
return $saved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes PDF alpha after it's been read.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*/
|
||||
protected function remove_pdf_alpha_channel() {
|
||||
$version = Imagick::getVersion();
|
||||
// Remove alpha channel if possible to avoid black backgrounds for Ghostscript >= 9.14. RemoveAlphaChannel added in ImageMagick 6.7.5.
|
||||
if ( $version['versionNumber'] >= 0x675 ) {
|
||||
try {
|
||||
// Imagick::ALPHACHANNEL_REMOVE mapped to RemoveAlphaChannel in PHP imagick 3.2.0b2.
|
||||
$this->image->setImageAlphaChannel( defined( 'Imagick::ALPHACHANNEL_REMOVE' ) ? Imagick::ALPHACHANNEL_REMOVE : 12 );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'pdf_alpha_process_failed', $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.5.0
|
||||
* @since 6.0.0 The `$filesize` value was added to the returned array.
|
||||
|
||||
BIN
tests/phpunit/data/images/test-alpha.pdf
Normal file
BIN
tests/phpunit/data/images/test-alpha.pdf
Normal file
Binary file not shown.
@@ -641,4 +641,54 @@ class Tests_Image_Editor_Imagick extends WP_Image_UnitTestCase {
|
||||
|
||||
$this->assertNotWPError( $saved );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the alpha channel of PDFs is removed from PDF previews.
|
||||
*
|
||||
* Only affects systems with Ghostscript version >= 9.14.
|
||||
*
|
||||
* @ticket 39216
|
||||
*
|
||||
* @covers WP_Image_Editor_Imagick::remove_pdf_alpha_channel
|
||||
*/
|
||||
public function test_remove_pdf_alpha_channel_should_remove_the_alpha_channel_in_preview() {
|
||||
if ( ! wp_image_editor_supports( array( 'mime_type' => 'application/pdf' ) ) ) {
|
||||
$this->markTestSkipped( 'Rendering PDFs is not supported on this system.' );
|
||||
}
|
||||
|
||||
$test_file = DIR_TESTDATA . '/images/test-alpha.pdf';
|
||||
$attachment_id = $this->factory->attachment->create_upload_object( $test_file );
|
||||
$this->assertNotEmpty( $attachment_id, 'The attachment was not created before testing.' );
|
||||
|
||||
$attached_file = get_attached_file( $attachment_id );
|
||||
$this->assertNotEmpty( $attached_file, 'The attached file was not returned.' );
|
||||
|
||||
$rgb = array(
|
||||
'r' => true,
|
||||
'g' => true,
|
||||
'b' => true,
|
||||
);
|
||||
|
||||
// White.
|
||||
$expected = array(
|
||||
'r' => 1,
|
||||
'g' => 1,
|
||||
'b' => 1,
|
||||
);
|
||||
|
||||
$check = image_get_intermediate_size( $attachment_id, 'full' );
|
||||
$this->assertIsArray( $check, 'The intermediate size could not be retrieved.' );
|
||||
$this->assertArrayHasKey( 'file', $check, 'The intermediate size file was not found.' );
|
||||
|
||||
$check_file = path_join( dirname( $attached_file ), $check['file'] );
|
||||
$imagick = new Imagick( $check_file );
|
||||
$output = array_map(
|
||||
static function( $value ) {
|
||||
return (int) round( $value );
|
||||
},
|
||||
array_intersect_key( $imagick->getImagePixelColor( 100, 100 )->getColor( true /* normalized */ ), $rgb )
|
||||
);
|
||||
$imagick->destroy();
|
||||
$this->assertSame( $expected, $output, 'The image color of the generated thumb does not match expected opaque background.' ); // Allow for floating point equivalence.
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user