Fix alpha transparency in XCF images
authorBrian Wolff <bawolff+wn@gmail.com>
Fri, 4 Jul 2014 04:46:10 +0000 (01:46 -0300)
committerBrian Wolff <bawolff+wn@gmail.com>
Fri, 4 Jul 2014 04:50:39 +0000 (01:50 -0300)
The -layers merge option flattens all layers on to a canvas
of whatever color -background is set to. However -background
was white for the PNG bKGD chunk. Set it to transparent just
for the -layers merge operation.

This works well on most recent image magick. Older image magick
explodes on my test image (I tested 6.6.0-4), so unclear if it
works there, but it certainly didn't make anything worse.
Wikimedia uses a version between the two that I tested so hopefully
this will make things better, and if it doesn't, it eventually will
when we update image magick.

Bug: 35622
Change-Id: I77601cdf005a64ae8ea7516cc846620431917863

includes/media/Bitmap.php

index 76dab03..bf50f2d 100644 (file)
@@ -354,7 +354,17 @@ class BitmapHandler extends ImageHandler {
                                }
                        }
                } elseif ( $params['mimeType'] == 'image/x-xcf' ) {
-                       $animation_post = array( '-layers', 'merge' );
+                       // Before merging layers, we need to set the background
+                       // to be transparent to preserve alpha, as -layers merge
+                       // merges all layers on to a canvas filled with the
+                       // background colour. After merging we reset the background
+                       // to be white for the default background colour setting
+                       // in the PNG image (which is used in old IE)
+                       $animation_post = array(
+                               '-background', 'transparent',
+                               '-layers', 'merge',
+                               '-background', 'white',
+                       );
                        wfSuppressWarnings();
                        $xcfMeta = unserialize( $image->getMetadata() );
                        wfRestoreWarnings();