Opacity masking an image

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?".
Wimweb

Opacity masking an image

Post 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?
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Opacity masking an image

Post 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
Wimweb

Re: Opacity masking an image

Post 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?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Opacity masking an image

Post by fmw42 »

Jpg does not preserve transparency. You need to use gif or png for output
Wimweb

Re: Opacity masking an image

Post 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?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Opacity masking an image

Post by fmw42 »

Not sure I understand your problem. Have you tried swapping the image order.

See http://www.imagemagick.org/Usage/compose/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Opacity masking an image

Post 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
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Wimweb

Re: Opacity masking an image

Post 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?
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Opacity masking an image

Post 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.
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Opacity masking an image

Post 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");
?>
Wimweb

Re: Opacity masking an image

Post by Wimweb »

It is still the same. I tried both suggestions, but they don't help. Thanks anyway.

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

Re: Opacity masking an image

Post 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!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Wimweb

Re: Opacity masking an image

Post 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?
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Opacity masking an image

Post 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.
Wimweb

Re: Opacity masking an image

Post 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!
Post Reply