Page 1 of 1

Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-04T13:55:20-07:00
by badabou
Hello,

I would get the number of transparent pixels (or percentage) in an image, is this possible ?

In order to know whether I should or not apply a transparent optimization (OptimizeTransparency -layers) to an animated gif (because a gif already transparent do not support this optimization).

Thank you very much.

Re: Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-04T14:42:48-07:00
by fmw42
convert image.png -channel a -separate -format "%[fx:100*mean]%" info:

This computes the mean of the alpha channel with 100% being totally transparent and 0 be totally opaque

Re: Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-05T01:01:07-07:00
by badabou
That's exactly what I wanted. Thank you very much!

Re: Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-05T22:46:09-07:00
by anthony
The OptimizeTransparency should not care if the image has transparency or now.
Though if the images do not have a transparancy color it will try to add one to the color table.

All it does is work out what the 'dispose' image of the last frame looks like (after the set disposal method has been applied), and then compare this with the pixels that the current frame overlays. If the pixel value does not change the overlay does not need to change the pixel, so it makes that pixel transparent. If you get a good number of transparent pixels (especially with complex backgrounds) you get a compression optimized saving.

It makes no difference if the image already has transparency!

Re: Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-06T00:04:29-07:00
by badabou
You're right but when I do not change the matte value depending on whether there is transparency or not, the final gif file (optimized) has holes transparent pixels across incorrect.

Here is the solution I found which seems to work:

Code: Select all

$result = shell_exec('convert '.$fileMiff.' -channel a -separate -format "%[fx:100*mean]%" info:');

$tabPercent = explode("\n", trim($result));
		
$op = ($tabPercent[0] > 1 ? '-':'+');
		
$fileGif = TMP_DIR.'optrans_'.uniqid().'.gif';
		
exec('convert '.$fileMiff.' '.$op.'matte -layers OptimizeTransparency '.$fileGif);

Re: Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-06T16:20:33-07:00
by anthony
Can you provide an example of the input and the problem?

It seems a little strange to me.

Re: Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-08T01:20:15-07:00
by badabou
With this 4 images :
http://nsa10.casimages.com/img/2009/10/ ... 385276.png
http://nsa10.casimages.com/img/2009/10/ ... 911261.png
http://nsa10.casimages.com/img/2009/10/ ... 277972.png
http://nsa11.casimages.com/img/2009/10/ ... 117853.png


# convert frame_000.png frame_001.png frame_002.png frame_003.png -layers OptimizeTransparency out.gif

Look at the beard of the figure. It contains transparent pixels.

Image


# convert frame_000.png frame_001.png frame_002.png frame_003.png -matte -layers OptimizeTransparency out.gif

Again

Image


# convert frame_000.png frame_001.png frame_002.png frame_003.png +matte -layers OptimizeTransparency out_with_matte.gif

There is perfect

Image

Re: Get the number (or perrcentage) of transparent pixels ?

Posted: 2009-10-08T16:34:26-07:00
by anthony
Downloaded these as a1.png to a4.png
NOTE: you should specify a delay! even if browsers do what you want.

Avoiding the GIF format handling for the time being....

Code: Select all

   convert a?.png -delay 10 -layers OptimizeTransparency miff: | animate -
and the animation comes out perfectly.
Checking the optimized frames

Code: Select all

  convert a?.png -delay 10 -layers OptimizeTransparency miff: | gif_anim_montage 2x -
Looking at 'gif' version...

Code: Select all

  convert a?.png -delay 10 -layers OptimizeTransparency gif: | gif_anim_montage 2x -
and I can see differences in the parts you are complaining about.

Extracting the first frame (which is the only place which could have transparent pixels in the center region)

Code: Select all

convert a?.png -delay 10 -layers OptimizeTransparency gif: | \
   convert '-[0]' -alpha extract show:
shows a black dot everywhere their is a transparency issue.
going back to MIFF output..

Code: Select all

convert a?.png -delay 10 -layers OptimizeTransparency miff: | \
   convert '-[0]' -alpha extract show:
and the dots disappear.
Looking at the actual pixel data and I find the first image is actually semi-transparent in places.

The -layers OptimizeTransparency does not modify the first frame. only the second and later frames based on differences. As such these semi-transparent pixels must be in the source image. and they are. In image a1.png. Actually they are in ALL your images, and the center region are matched as being equivalent!

Your input images are NOT fully opaque.

That is the cause of your problems.

Indeed

Code: Select all

  identify -verbose a1.png
...
alpha:
min: 11822 (0.180392)
max: 65535 (1)
mean: 65301.5 (0.996437)
standard deviation: 2731.65 (0.0416823)
kurtosis: 133.565
skewness: 11.6296
...
Alpha should have been fully opaque.

Code: Select all

convert a1.png -alpha extract -verbose info:
...
Histogram:
4: (11822,11822,11822) #2E2E2E2E2E2E grey18
2192: (33410,33410,33410) #828282828282 grey51
300304: (65535,65535,65535) #FFFFFFFFFFFF white
...
You have at more than 2000 semi-transparent pixels in your first image!


This is why +matte is needed -- to make all pixels full opaque first!

So either use +matte, for this specific animation. or fix the method used to create the frames.