3

I'm trying to remove the alpha channel (transparency) of a PNG file and replace it with a white background in PHP.

Using ImageMagick I've tried several functions with no luck so far. These are the function which didn't work:

    $iMagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_DEACTIVATE);
    $iMagick->setImageBackgroundColor('#FFFFFF');
    $iMagick = $iMagick->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);

Also setBackgroundColor('#FFFFFF') instead of setImageBackgroundColor('#FFFFFF') didn't help. Same to replacing '#FFFFFF' with 'white' in these 2 functions.

Using ImageMagick 3.4.0RC6 (release date: 2016-11-29) compiled with ImageMagick 6.8.9-9 Q16 x86_64 2016-03-14. Current versions (Ubuntu 16.04).

Any ideas? Thanks in advance
ninsky

ninsky
  • 1,772
  • 23
  • 31

2 Answers2

6

Just omit your first line of code which deactivates the transparency and run with:

$iMagick->setImageBackgroundColor('#FFFFFF');
$iMagick = $iMagick->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • I've tried that and testet with Imagick's identify -verbose. Got: "Channel depth: red: 8-bit, green: 8-bit, blue: 8-bit, alpha: 1-bit. Transparent color: none". So I think this did the trick. Thanks! – ninsky Dec 12 '16 at 18:48
  • 1
    @peter Imagine a stack of images, each one with some see-through bits in it (transparent areas). First, put a white sheet of paper on your desk, i.e. `BackgroundColor(white)`, now lay all the other images with transparent areas on top. The nett effect is you will see white they are all transparent. – Mark Setchell Dec 22 '17 at 11:55
1

Here is a function I'm using. It's not based on ImageMagick, though. Took it from another stackoverflow answer and customized it to only colorize transparent pixels.

function colorizeTransparent( $file, $targetR, $targetG, $targetB, $targetName ) {

        $im_src = imagecreatefrompng( $file );
        $width = imagesx($im_src);
        $height = imagesy($im_src);
        $im_dst = imagecreatefrompng( $file );

        for( $x=0; $x<$width; $x++ ) {
            for( $y=0; $y<$height; $y++ ) {
                $rgba = imagecolorat( $im_src, $x, $y );
                $alpha = ($rgba & 0x7F000000) >> 24;
                if ($rgba == 0) {
                    $col = imagecolorallocatealpha( $im_dst,
                        $targetR - (int) ( 1.0 / 255.0  * $alpha * (double) $targetR ),
                        $targetG - (int) ( 1.0 / 255.0  * $alpha * (double) $targetG ),
                        $targetB - (int) ( 1.0 / 255.0  * $alpha * (double) $targetB ),
                        $alpha
                    );
                } else $col = $rgba;
                imagesetpixel( $im_dst, $x, $y, $col );
            }
        }
        imagepng( $im_dst, $targetName);
    }

Call the function this way:

colorizeTransparent($sourceImage, 0xFF, 0xFF, 0xFF, $colorizedImage);

With $sourceImage being the source filename and $colorizedImage being the destination filename.

Let me know how that worked out for you.

Idan
  • 402
  • 1
  • 5
  • 22