Imagick / ImagickDemos

An example of all the Imagick functions
Other
130 stars 37 forks source link

Unable to set image alpha channel with setImageAlphaChannel method #22

Open hengsoheak opened 7 years ago

hengsoheak commented 7 years ago

I'm trying to create transparent image with ImageMagick with the backgroundMasking method which I found on http://phpimagick.com/Tutorial/backgroundMasking but I got errors as below messages.

This is my ImageMagick invironment

Version: ImageMagick 7.0.5-4 Q16 x86_64 2017-04-03 http://www.imagemagick.org Copyright: © 1999-2017 ImageMagick Studio LLC License: http://www.imagemagick.org/script/license.php Features: Cipher DPC HDRI OpenMP Delegates (built-in): bzlib djvu fontconfig freetype gvc jbig jng jpeg lcms lqr lzma openexr png tiff wmf x xml zlib

However I've run ./configure --enable-hdri --with-quantum-depth=32 and make install commend but I'm still facing this problem.

Problem

Unable to set image alpha channel

function backgroundMasking()
 {
    //Load the image
    $imagick = new \Imagick(realpath('images/chair.jpeg'));

    $backgroundColor = "rgb(255, 255, 255)";
    $fuzzFactor = 0.1;

    // Create a copy of the image, and paint all the pixels that
    // are the background color to be transparent
    $outlineImagick = clone $imagick;
    $outlineImagick->transparentPaintImage(
        $backgroundColor, 0, $fuzzFactor * \Imagick::getQuantum(), false
    );

    // Copy the input image
    $mask = clone $imagick;
    // Deactivate the alpha channel if the image has one, as later in the process
    // we want the mask alpha to be copied from the colour channel to the src
    // alpha channel. If the mask image has an alpha channel, it would be copied
    // from that instead of from the colour channel.
    $mask->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
    //Convert to gray scale to make life simpler
    $mask->transformImageColorSpace(\Imagick::COLORSPACE_GRAY);

    // DstOut does a "cookie-cutter" it leaves the shape remaining after the
    // outlineImagick image, is cut out of the mask.
    $mask->compositeImage(
        $outlineImagick,
        \Imagick::COMPOSITE_DSTOUT,
        0, 0
    );

    // The mask is now black where the objects are in the image and white
    // where the background is.
    // Negate the image, to have white where the objects are and black for
    // the background
    $mask->negateImage(false);

    $fillPixelHoles = false;

    if ($fillPixelHoles == true) {
        // If your image has pixel sized holes in it, you will want to fill them
        // in. This will however also make any acute corners in the image not be
        // transparent.

        // Fill holes - any black pixel that is surrounded by white will become
        // white
        $mask->blurimage(2, 1);
        $mask->whiteThresholdImage("rgb(10, 10, 10)");

        // Thinning - because the previous step made the outline thicker, we
        // attempt to make it thinner by an equivalent amount.
        $mask->blurimage(2, 1);
        $mask->blackThresholdImage("rgb(255, 255, 255)");
    }

    //Soften the edge of the mask to prevent jaggies on the outline.
    $mask->blurimage(2, 2);

    // We want the mask to go from full opaque to fully transparent quite quickly to
    // avoid having too many semi-transparent pixels. sigmoidalContrastImage does this
    // for us. Values to use were determined empirically.
    $contrast = 15;
    $midpoint = 0.7 * \Imagick::getQuantum();
    $mask->sigmoidalContrastImage(true, $contrast, $midpoint);

    // Copy the mask into the opacity channel of the original image.
    // You are probably done here if you just want the background removed.
    $imagick->compositeimage(
        $mask,
        \Imagick::COMPOSITE_COPYOPACITY,
        0, 0
    );

    // To show that the background has been removed (which is difficult to see
    // against a plain white webpage) we paste the image over a checkboard
    // so that the edges can be seen.

    // Create the check canvas
    $canvas = new \Imagick();
    $canvas->newPseudoImage(
        $imagick->getImageWidth(),
        $imagick->getImageHeight(),
        "pattern:checkerboard"
    );

    // Copy the image with the background removed over it.
    $canvas->compositeimage($imagick, \Imagick::COMPOSITE_OVER, 0, 0);

    //Output the final image
    $canvas->setImageFormat('png');
    header("Content-Type: image/png");
    echo $canvas->getImageBlob();
 }
Danack commented 7 years ago

Unable to set image alpha channel

That's the whole output?

Which line does it occur on?

hengsoheak commented 7 years ago

Dear Danack,

Errors : Unable to set image alpha channel (On Method $imagick->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);) URL : http://camvgo.com/game/cards/2#

hengsoheak commented 7 years ago

Does it require any package to run this services?

Danack commented 7 years ago

@hengsoheak The stack trace you provided is nothing like the code sample you originally posted.

Please post a reproducible example if you want me to investigate. I don't have time to guess what code is actually being run.

However, there's a reasonable chance you've just cocked up your computer by installing ImageMagick 7, but also are using a version of Imagick that was compiled against ImageMagick 6, as the value of \Imagick::ALPHACHANNEL_DEACTIVATE should be 5 on ImageMagick 7, but in your stack trace it seems to have the value of 4, if that is what the code is actually calling.

There is actually code in place to detect that situation and give a warning....but maybe it's not working or you've just disabled/ignored that warning?