Page 1 of 1

PNG alpha channel problem

Posted: 2014-05-30T15:26:26-07:00
by stevew
Using the PHP API, I'm capturing a user's hand written signature and attempting to make it a 32-bit transparent png to be overlayed on a PDF form. The code I have below actually works and displays in the browser fine but there is a problem with the png when it is opened in Photoshop or applied to a PDF document. When I open the png in Photoshop or insert it into a PDF it is solid blue.

Code: Select all

$sig = new Imagick();
$sig->readImageBlob($hex);  // this is an 8-bit grayscale bmp image
$sig->setImageDepth(32);  
$sig->negateImage(true);

$sig->setImageAlphaChannel (Imagick::ALPHACHANNEL_COPY);
$sig->floodFillPaintImage('blue', 0, 'blue', 0, 0, Imagick::CHANNEL_DEFAULT); 

$sig->setImageFormat('PNG32');
$sig->writeImage($fileName);;
Here's a live link to an image generated with this code.
Image

Re: PNG alpha channel problem

Posted: 2014-05-30T16:12:33-07:00
by snibgo
Your image has blue writing on a transparent blue backgound. Every single pixel is blue; only the alpha varies.

When I convert it to PDF (IM v6.8.9-0, Ghostscript v9.10), I get the expected blue writing on a transparent background.

I don't have Photoshop so can't test with that. But I can't see why there would be problems.

"identify -verbose" shows the image has gamma=1, which is unsual. Gamma=0.454545 (sRGB) would be more common. That should make no dfference to this image, as all pixels are (0,0,255), so gamma has no effect.

Re: PNG alpha channel problem

Posted: 2014-05-30T16:39:40-07:00
by fmw42
This will fix it -- tested with PS CS (so kind of old). Sets the background under the transparency to black leaving the background blue where there is writing in the alpha channel.

Code: Select all

convert 13839_Darth_Vader.png -background black -alpha background 13839_Darth_Vader2.png

Here is a better way to generate it if you are starting with black writing on white background (as signature.png). This should be compatible with PS

Code: Select all

convert signature.png -fuzz 50% -fill blue -opaque black -transparent white result.png
Adjust the fuzz value to suit for thickness of the signature.

Re: PNG alpha channel problem

Posted: 2014-06-01T22:03:00-07:00
by stevew
Thanks for your input. I followed the advice but it only gave me a workaround and I just wasn't satisfied with that. I really wanted the authentic, semitransparent anti-aliasing. There was only one problem with my solution and it turned out to be a quirky issue with Imagick itself. So for the benefit of future generations, here is the solution:

$sig = new Imagick();
$sig->readImageBlob($hex); // this is an 8-bit grayscale bmp image, black signature on white background

// I don't know/care if this is all necessary but it ensures I end up with the intended file format
$sig->setImageType(Imagick::IMGTYPE_TRUECOLORMATTE);
$sig->setImageColorspace (imagick::COLORSPACE_RGB);
$sig->setImageDepth(32);
$sig->setImageFormat('PNG32');

$sig->negateImage(true);

// this is the correct way to acheive a colored shape in Imagick
$sig->setImageBackgroundColor('blue');
$sig->setImageAlphaChannel (Imagick::ALPHACHANNEL_SHAPE);

$sig->writeImage('PNG32:'.$fileName); // saving with the PNG32 designation before the file name was the key! Otherwise Imagick was saving as an 8 bit png format regardless of the directions I gave it above. Many Bothans died to bring us this information.

Re: PNG alpha channel problem

Posted: 2014-06-01T22:14:07-07:00
by fmw42
$sig->setImageDepth(32);
I do not think this is realistic or applicable if you are not using Q32 IM. If you are on Q16 or Q8, the best you can do is depth 16 or 8, respectively. depth in IM is per channel, not per pixel. PNG32: ensures you have 8-bits per channel including the alpha channel

Re: PNG alpha channel problem

Posted: 2014-06-02T08:31:43-07:00
by stevew
fmw42 wrote:
$sig->setImageDepth(32);
I do not think this is realistic or applicable if you are not using Q32 IM. If you are on Q16 or Q8, the best you can do is depth 16 or 8, respectively. depth in IM is per channel, not per pixel. PNG32: ensures you have 8-bits per channel including the alpha channel
Confirmed that it works just fine without that.