Is it possible to combine 2 images & make a transparent PNG?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by fmw42 »

I am not quite sure I know exactly how you want these two combined. But you can do something like what you have by the following with a 75% opacity where it is just blue (using a checkerboard background as I don't have your striped background).

convert tcw.png \( tcb.png -fill white -opaque "rgb(255,0,0)" -fill white -opaque "rgb(68,22,187)" -fill gray75 -opaque "rgb(0,22,187)" \) +matte -compose copy_opacity -composite tcw_t75.png

convert \( -size 214x208 pattern:checkerboard \) tcw_t75.png -composite tcw_t75_checks.png

or with just the white background image as follows:

convert tcw.png \( +clone -fill black -opaque white -fill white -opaque "rgb(255,0,0)" -fill white -opaque "rgb(68,22,187)" -fill gray75 -opaque "rgb(68,90,255)" \) +matte -compose copy_opacity -composite tcw_t75.png

convert \( -size 214x208 pattern:checkerboard \) tcw_t75.png -composite tcw_t75_checks.png
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by el_supremo »

Changing the backgrounds to transparent is easy in this case because the colours are known:

Code: Select all

convert tcb.png -transparent black tcbo.png
convert tcw.png -transparent white tcwo.png
and then combine them:

Code: Select all

composite tcwo.png tcbo.png -dissolve "10%" tcz.png
You'll have to play with the 10% value to get what you want.

Best Wishes
Pete
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by fmw42 »

Pete,

I think he needs to have some of the blue partially transparent, so I had to go to extremes. Your dissolve however may be important as the blue parts were different colors in the two images and I did not know if that was important.

He needs to clarify how he wanted the two images combines and what parts need to be partially transparent.

Fred
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by el_supremo »

Hi Fred,
I think he needs to have some of the blue partially transparent
Ah yes, now I see. Haven't figured out how to do that yet.

Pete
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by anthony »

I think I understand, you want to calculate the transparency needed to restore the original image, basied on a an overlay of the original on pure white and pure black.

hmmm that is a interesting problem, and one that has the practical application of the restorting the semi-transparent backgrounds (including anti-aliasing edging pixels to images from two Web GIF images.

Hmm. well first anything with a maximum difference will be
fully-transparent, while any pixel that has no differences at all
will be fully-opaque. Its when color gets involved that things get tricky.

NOTE: you will have an error if you get a lighter color on the black background image to the color that appears on the white background image!!!

Well. first of all the appropriate shade of blue is -- the average of the two color shades.. It would have been lightened and darkend by the same amount, so the average
of the image two images should be the correct original color!!!

Second the difference between the two colors should be amount of transparency involved (or at least simply related to it) so a difference image will be a good first try. If the difference image is a greyscale! then I would say you have the solution!

So lets try this...
Extract the original colors (average)...

Code: Select all

convert tcb.png tcw.png -average tc_colors.png
And the amount of transparency (difference)...

Code: Select all

convert tcb.png tcw.png -compose difference -composite tc_diff.png
And what do you know- its greyscale. that is a good sign!!

so to get the original image with appropriate transparency, use the a negated difference image as a mask for the average color image.

Code: Select all

convert tc_colors.png \( tc_diff.png -negate \) +matte -compose CopyOpacity -composite tc_restored.png
the result look pretty good, to what I would expect to see for the original image. A fully-opaque red, with a semi-transparent blue.

As a check lets overlay this on white and compare it to the
original 'white background' image.

Code: Select all

convert tc_restored.png -background white -flatten tcw.png -compose difference -composite -unique-colors txt:-
# ImageMagick pixel enumeration: 2,1,255,rgba
0,0: ( 0, 0, 0, 0) #000000 black
1,0: ( 25, 19, 25, 0) #191319 rgb(25,19,25)
Hmmm it is VERY close but not quite exactly correct, as the 'blue' area shows some, very very slight differences

Anyone else like to have a go, or like to figure out where my working is wrong? Perhaps it isn't an average for calculating the colors?

The final solution will of course be posted on IM Examples. here is your chance to be credited on this web site!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by anthony »

After studying the values for the blue in th two images. I have come to the conclusion that the semi-transparent blue area did not originate from the same initial color value.

The semi-transparent blue has the same 'red' component in it regardless of if the blue was overlayed on a white or black background. where the red component should have also become lighter or darker by the same percentage as the other two components. This is not the case.

I'll try to set up a separate test starting image, overlay that onto white and black, and try to restore from that, to see if I have my working correct.

Code: Select all

 convert rose: \( -size 46x70 gradient: -rotate -90 \) +matte -compose copyopacity -composite rose_orig.png
convert rose_orig.png -background white -flatten rose_white.png
convert rose_orig.png -background black -flatten rose_black.png
convert rose_white.png rose_black.png -average rose_avg.png
convert rose_white.png rose_black.png -compose difference -composite rose_diff.png
convert rose_avg.png \( rose_diff.png -negate \) +matte -compose copyopacity -composite rose_restored.png
the result is again not quite right. the restored image is close to that of the original, but it is not an exact match.
Both the colors, and the transparency do not quite match up.

Anyone else like to give this a go?
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
m0dest
Posts: 1
Joined: 2018-08-07T00:40:53-07:00
Authentication code: 1152

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by m0dest »

In case anyone has the same need, I found a (provable) solution to this problem.

The Math

Solving for alpha and color channel value using the opacity algorithm (over operator: https://en.wikipedia.org/wiki/Alpha_com ... r_operator), you can derive the following:

1. Original alpha value of a pixel:

Code: Select all

1 - original_alpha = color_value_on_white_bg - color_value_on_black_bg
color_value_on_black_bg is the decimal R, G, or B value when placed on a black background.

2. Original RGB color value of a pixel:

Code: Select all

original_color_value = color_on_black_bg / original_alpha
original_alpha is the value derived above. original_color_value is the decimal R, G, or B value without transparency.


How To

To goal is to derive the original transparent image (an RGBA "overlay") based on 2 input images:
  • (1) The overlay image on top of a black matte background, named overlay-on-black-matte.png
  • (2) The overlay image on top of a white matte background, named overlay-on-white-matte.png
1. Derive the original alpha mask
Following #1 above, we want to subtract the black image from the white image, then invert the result.

Code: Select all

convert overlay-on-white-matte.png overlay-on-black-matte.png -compose difference -composite -channel RGB -negate tmp-overlay-alpha.png
tmp-overlay-alpha.png is the original alpha mask (as an opaque grayscale RGB image).

2. Derive the original colors
Following #2 above, we want to start with the black image and divide the original alpha mask.

Code: Select all

convert overlay-on-black-matte.png tmp-overlay-alpha.png -compose DivideSrc -composite tmp-overlay-rgb.png
tmp-overlay-rgb.png is the original RGB color image without an alpha mask.

3. Apply the original alpha mask to the original colors.

Code: Select all

convert tmp-overlay-rgb.png tmp-overlay-alpha.png -alpha Off -compose CopyOpacity -composite output-original-overlay.png
output-original-overlay.png is generated with the original RGBA transparent overlay image


Caveats
  • Subpixel anti-aliasing of fonts will not be recovered correctly, as subpixel anti-aliasing does not follow normal opacity rules.
  • Values may be very slightly different from source values due to loss of precision. Standard PNGs use 8-bit channels. It is impossible to derive the exact 32-bit RGBA values of the original image due to rounding. For those concerned with precsion, there is a slightly more accurate version below that uses 64-bit RGBA for the intermediary images.

Variant: Preserving more precision with PNG64 intermediate images
To lose less precision due to bit depth limitations, 16-bit channels can be used for the intermediate images.

Code: Select all

convert overlay-on-white-matte.png overlay-on-black-matte.png -compose difference -composite -channel RGB -negate -depth 16 PNG64:tmp-overlay-alpha.png64
convert overlay-on-black-matte.png tmp-overlay-alpha.png64 -compose DivideSrc -composite -depth 16 PNG64:tmp-overlay-rgb.png64
convert tmp-overlay-rgb.png64 tmp-overlay-alpha.png64 -alpha Off -compose CopyOpacity -composite output-original-overlay.png
The resulting output-original-overlay.png is still a standard 32-bit RGBA PNG, but more accurate.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by fmw42 »

Seems like the original post(s) at the top of this topic have been removed. I did not initiate this post and was trying to answer a question from some other person.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Is it possible to combine 2 images & make a transparent PNG?

Post by anthony »

I think this is similar to the example...
http://www.imagemagick.org/Usage/maskin ... background

Two images same foreground different background... Recover the foreground on transparency.

Also see discussion "undo a composite -dissolve"
http://www.imagemagick.org/discourse-se ... hp?t=18235
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply