Page 1 of 2

Opacity masking an image

Posted: 2009-04-25T01:31:04-07:00
by Wimweb
Hello

For a Magic: The Gathering TCG card maker, I'm using Imagemagick from commandline within PHP. I'm now trying to use a mask on the illustration uploaded by the user.
Illustration :
Image

Mask 2:
Image
(mask 1 is the same except the black is transparant)

I've tried many things ($place is the uploaded illustration)

Code: Select all

"composite ".$place." images/mask2.png -alpha Off -compose Copy_Opacity ".$place

Code: Select all

"convert ".$place." images/mask1.png -compose DstIn -composite ".$place

Code: Select all

"composite ".$place." ".$place." images/mask1.png ".$place

Code: Select all

"convert ".$place." -mask images/mask1.png ".$place
Which one is right? What do I have to do?

Re: Opacity masking an image

Posted: 2009-04-25T06:12:25-07:00
by Bonzo
Is this the sort of result you want? Using a rounded rectangle rather than a circle but you can see the method.

Code: Select all

<?php
Setup the comand
$cmd = "-size 637x140 xc:none -fill white ".
" -draw \"roundRectangle 0,0 637,140 15,15\" ".
" albir.jpg -compose SrcIn -composite  ";

// Process
exec("convert $cmd rounded_corners.png ");
?> 
Image

Re: Opacity masking an image

Posted: 2009-04-25T09:34:44-07:00
by Wimweb
Thanks, that helped me A LOT! I edited it a bit, and I'm now using :

Code: Select all

convert images/mask1.png illustrations/uploaded.jpg -compose SrcIn -composite illustrations/uploaded.jpg
and it almost works! I now get :
Image
Just have to remove the 4 black things.. any idea?

Re: Opacity masking an image

Posted: 2009-04-25T10:01:25-07:00
by fmw42
Jpg does not preserve transparency. You need to use gif or png for output

Re: Opacity masking an image

Posted: 2009-04-26T11:03:09-07:00
by Wimweb
Thanks, this now works... Now I just need to put it on another image. I am using

Code: Select all

convert illustration.png card.gif -geometry +28+54 -compose Over -composite card.gif
It has to be pasted on card.gif, but nothing is done. What am I doing wrong?

Re: Opacity masking an image

Posted: 2009-04-26T15:31:31-07:00
by fmw42
Not sure I understand your problem. Have you tried swapping the image order.

See http://www.imagemagick.org/Usage/compose/

Re: Opacity masking an image

Posted: 2009-04-26T20:07:45-07:00
by anthony
Wimweb wrote:I've tried many things ($place is the uploaded illustration)

Code: Select all

"composite ".$place." images/mask2.png -alpha Off -compose Copy_Opacity ".$place
Swap the arguments. Source then background. See first example below.

Code: Select all

"convert ".$place." images/mask1.png -compose DstIn -composite ".$place
Both images are fully opaque, a Duff-Porter composite operators (like DstIn) only work with images that have transparency, However it regards the area around a source image proper (if source image does not full cover the destination or background) as being transparent. Such operators do not understand grayscale masks, only alpha channel (thus the term -alpha composition).

See LAST example below which converts the greyscale mask into a shaped or alpha mask for a 'dst_in' operator.

Code: Select all

"composite ".$place." ".$place." images/mask1.png ".$place
Overlaying the same image on itself will result in that image regardless of which image the third image mask says it should be using.

Note the two images being masked together is NOT source and background, but the composite result and background. As the compose operator is over and the two images are the same you are still masking the same image (source over background) with the same image giving the same image.

See the second example below, which uses a single pixel transparent image, with a 'src' operator so the result image from the composition is a transparent image the same size as the background. This is then (third image) masked against the background image. The mask is of course thought to be a gray scale mask in a three image composite.


Any of these!

Code: Select all

composite  images/mask2.png $place -alpha Off -compose Copy_Opacity $place
composite xc:none $place images/mask2.png -composite Src $place
convert $place images/mask2.png -alpha Off -compose Copy_Opacity -composite $place
convert $place -alpha on \( images/mask2.png -alpha shape \) -composite dst_in -composite $place
remember for compose the order is source then background
for convert it is background then source

There are lots of ways to skin a cat, and what method you use depends
on what you want that skin for, and how messy you like the results!
-- Anthony Thyssen

Re: Opacity masking an image

Posted: 2009-04-27T11:55:52-07:00
by Wimweb
Hey guys,

Thanks for your help. Not there yet, but almost.
The image masking is done now. I now get this :
Image
(illustration.png) (well, imageshack makes the transparent black..)
And I need to paste it on this :
Image
(card.gif)

And I use the command

Code: Select all

convert card.gif illustration.png -geometry +28+54 -compose Over -composite card.gif
Any ideas?

Re: Opacity masking an image

Posted: 2009-04-27T12:11:30-07:00
by Bonzo
Why did you bother doing the first mask ?
Anyway this should do what you want for the last step:

Code: Select all

<?php
exec("convert imageshackcard.gif 1240858032pic62f4tmp.png -geometry +28+54 -composite merged.jpg");
?>
I would have cropped the first image to the same size as imageshackcard.gif and then just done this step.

Re: Opacity masking an image

Posted: 2009-04-27T12:31:30-07:00
by Bonzo
As the "background" image is smaller than the "foreground" image I had to pad it out a bit:

Code: Select all

<?php
exec("convert \( 1240646276pic62f4tmp.jpg -resize 340x470 -gravity center -extent 340x470 \) imageshackcard.gif -composite +repage merged1.jpg");
?>

Re: Opacity masking an image

Posted: 2009-04-29T07:19:11-07:00
by Wimweb
It is still the same. I tried both suggestions, but they don't help. Thanks anyway.

any suggestions?

Re: Opacity masking an image

Posted: 2009-04-29T17:45:28-07:00
by anthony
Okay... lets take this back to first principles. Though it is rather like the examples for 'simple border overlays'
http://www.imagemagick.org/Usage/thumbn ... er_overlay

From "imageshack" I downloaded "illustration.jpg" (the main image) and "card.gif" (the surrounding 'border' image) that you want to insert the illustration into.

First forget the mask, it is not important. The "card.gif" image itself already has a 'hole' in it which can be used to mask the illustration image directly.

However as you are using a GIF image, which only allows boolean transparency, the hole will have a highly 'aliased' (stair-cased') edge to it. That is not very good, and I recommend you convert "card.gif" into PNG format, flatten it on black, and re-cut the hole either using a GUI image editor (such as GIMP or photoshop) or using the mask you previous supplied.

This re-masking of the "card" image is only needed once, and saved as PNG (not GIF), even though your final image may be GIF.

Second you want the resulting image to be the size of the "card.gif" so that makes it the "background" image.

Third You will thus want to place the illustration UNDER that card so that means you need to use
a DstOver composition method. See IM Examples Duff-Porter Compose Methods and more specifically Dst Over, or compose 'under' destination


So lets do this with a Center gravity, and then adjust the geometry offset until the illustration is correctly centered in the card hole. As the images are gravity centred this offset will remain the same regardless of the size of the illustration. You can resize, scale, pad or distort the illustration as you like and it will still position correctly with the same offset.

Code: Select all

convert card.gif illustration.jpg  -geometry +0-17 \
             -gravity center  -compose DstOver -composite result.png
ASIDE: the card hole is not very symmetrical!

Now normally the illustration should completely 'fill' the hole in the "background" card image, but in this case the illustration does not even touch the edges of the hole!!!!

Fill with black...

Code: Select all

convert card.gif illustration.jpg  -geometry +0-17 \
             -gravity center  -compose DstOver -composite \
             -compose Over  -background black -flatten result.png
Resize illustration a bit larger

Code: Select all

convert card.gif \( illustration.jpg -resize x300 \) -geometry +0-17 \
             -matte -gravity center  -compose DstOver -composite \
             -compose Over  -background black -flatten result.png
You can finish the task by making the corners of the card transparent using...
http://www.imagemagick.org/Usage/thumbnails/#rounded

There that is the full solution!

Re: Opacity masking an image

Posted: 2009-04-30T09:25:39-07:00
by Wimweb
Ok, I only tried the first thing yet, but I still don't get an image. I vardumped my commands, and this is what I get (well, the ones that are relevant to my illustrations) :

Code: Select all

string(104) "convert illustration.png -resize 303x334! illustration.png"
string(193) "convert card.gif illustration.png -geometry +0-17 -gravity center -compose DstOver -composite card.gif" 
I really don't get what I'm doing wrong (In my code the images are named different, because illustration.png is uploaded by the user, and other things are done (in IM) with card.gif)

And, why does the illustration need to have the size of the card?

Re: Opacity masking an image

Posted: 2009-04-30T12:10:14-07:00
by Bonzo
I really don't get what I'm doing wrong (In my code the images are named different, because illustration.png is uploaded by the user, and other things are done (in IM) with card.gif)

And, why does the illustration need to have the size of the card?
At this stage do not worry about what you are going to do just get Anthonys example to work and you can modify it later.
Ok, I only tried the first thing yet, but I still don't get an image.
What have you tried? Post your code. Where is an example of what your results?

Start off with something simple, get it to work and you can do whatever you want with it when its working.

Re: Opacity masking an image

Posted: 2009-04-30T13:17:33-07:00
by Wimweb
Thanks very much guys.
Anthony, your solution worked after all.
I just made an error in my code in which the card.gif was remade after the illustration was put on it... Stupid of course.

Problem solved, Thank you!