ImageMagick Convert: how to add alpha shadows upon RGB image? - image-processing

Given a RGB image :
Given a grey scale, opacity 0% to opacity 100% black image:
How to add the alpha shadows upon the RGB image using a shell command ? (preferemce for ImageMagick Convert)

I would compose the images using the Multiply operator. The command
convert src.png overlay.png -compose Multiply -geometry 948x630 -composite out.png
produces:

I believe the example "Using Masks with Images" covers this. Simply disable the alpha channel, and copy over the second image as opacity composite. Add -negate option to invert the 0% ~ 100% opacity -- if needed.
convert map_image.png elevation_mask.png \
-alpha Off -compose CopyOpacity -composite \
out.png

Related

How to add a border to a transparent PNG using ImageMagick, while preserving transparency?

I am trying to add a 10px red border to a transparent PNG using ImageMagick, while preserving any existing transparency that might exist within the image. Here is my source image:
If you download and view that image with an image viewer, you'll see that it has a transparent background.
According to everything I've read, the following Imagemagick command should add a 10px red border to the image:
convert input.png -bordercolor red -border 10 output.png
It actually does add the red border to the image, since the output dimensions are 20px larger in both directions. Unfortunately it also changes the background color of the image to red as well. Here is the output file:
I do not want the transparent area to be changed to red. I only want to add a red border around the transparent image.
I've tried using both ImageMagick version 6.9.10-23 (Ubuntu) and 7.1.0 (via CloudConvert API), with the same result. I've spent hours(!) trying to solve this.
What am I doing wrong?
I found the answer in this thread: https://legacy.imagemagick.org/discourse-server/viewtopic.php?t=31843 . Here are the two money quotes:
So, "-bordercolor red -border 2" should create an opaque red image 2
pixels larger than the input, and composite the input over this. As
your input is "-size 100x100 xc:none", the result should be 102x102
opaque red pixels. You might think this is "pretty obviously
incorrect", but it is the documented behaviour.
and
Nevertheless, you can get it to work to have the transparent inside,
if you add -compose copy before -bordercolor red -border 2 in both the
current IM 6 and IM 7. This just may have to be the way to do it from
here on, if there is a good reason for the changed behavior.
Here is the command that produces the result I am after:
convert -background transparent -bordercolor red -compose Copy -border 10 input.png output.png
Here's an answer that fully preserves the transparency
convert input.png +write mpr:INP -alpha extract -morphology dilate disk:10 \\( +clone -fill Black -colorize 100 \\) +swap -compose CopyOpacity -composite mpr:INP -compose Over -composite output.png
From https://legacy.imagemagick.org/Usage/crop/#extent
Here is a simple way to do that in Imagemagick. Change the compose setting from over to copy.
Input:
convert logo_transp.png -compose copy -bordercolor red -border 10 logo_transp_border.png

ImageMagick - flatten of more png images

I have more PNG images (let's say img1.png, img2_transparent.png, img3.png) and I want them flatten to one image.
Before I flatten them I set (I want second image was slightly transparent):
convert img2_transparent.png -alpha on -channel a -evaluate set 90%
Then I flatten them (order is img1.png, img2_transparent.png, img3.png):
convert *.png -flatten out.png
Result is ok, second "layer" has opacity 90%, BUT whole picture (thus all "three" layers) is "lightened". Colors are not so deep as I don't set alpha to img2_transparent.png.
How can I avoid this?
Thank you
If you want the images to show up in equal measure in the resulting image, the general formula is to set the opacity of each layer to
1/(1 + number of layers underneath)
where the base layer is at full opacity. The second image is then at opacity 1/2, the third image at opacity 1/3, the fourth image is at opacity 1/4.
convert base.png \
\( layer2.png -channel A -fx '0.5' \) \
\( layer3.png -channel A -fx '0.333' \) \
\( layer4.png -channel A -fx '0.25' \) ....
There is a well explained tutorial on Cambridge in Colour website. Scroll down to AVERAGING IMAGES IN PHOTOSHOP USING LAYERS.

How to select all grayscale colors?

In ImageMagick convert, I can select a specific color with e.g. -opaque blue. How can I select all grayscale colors (e.g. #000000, #707070, #ffffff)?
Not sure what you are trying to do, but this may help. The greyscale pixels will have a saturation of zero, so that is probably the easiest way to identify them.
First, make a funky sample image:
convert -size 400x100 gradient:black-white -bordercolor red -border 80 image.png
Now make all grey areas (those with very low saturation) transparent:
convert image.png -alpha on -channel A -fx "saturation<0.01?0:1" result.png
Note
Note that the -fx operator is extremely powerful but notoriously slow because it is actually interpolated for each and every pixel. If your images are large, the following technique may be more appropriate.
Basically, I clone the image and convert the whole thing to HSL colorspace and separate the channels. Then I discard the Hue and Lightness channels so I am left with just the Saturation. I then threshold that and copy that back to the original image as the alpha channel. On a 2000x2000 pixel image, this method will run in under a second whereas the -fx method will require 5-6 seconds.
convert image.png \( +clone -colorspace hsl -separate -delete 0,2 -threshold 1% \) -compose copy-opacity -composite result.png

Compositing premultiplied images using ImageMagick

I have two images. One is background with no alpha. The other is a white cloud. The alpha of the cloud image is premultiplied with black. When I composite them the white cloud has black in it, so it looks grey instead of white like it should. I'm doing:
convert -gravity Center bg.tga whitecloud.tga -composite comp.tga
Is there a way to composite premultiplied images in ImageMagick, or does the image have to be non-premultiplied? Can I make a premultiplied image non-premultiplied using ImageMagick?
Update:
Ok, here are the images as TGA for download:
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/bg.tga
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/whitecloud.tga
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/aftereffects.tga
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/imagemagick.tga
and in the same order as jpgs to view in your browser:
I tried all the modes provided, but none of them create the same result as After Effects.
It would be easier if you showed your images, but try adding -compose lighten before -composite in your command, like this:
convert a.tga b.tga -compose lighten -composite out.tga
Basically that will make ImageMagick choose the lighter pixel of the two images at every point.
If that doesn't work, try other blending modes
for b in $(identify -list compose); do
convert -label "$b" bg.tga whitecloud.tga -compose $b -composite miff:-
done | montage - -tile 5x out.png
I am kind of thinking Atop, Dissolve, SrcAtop and SrcOver might be your friends but have a look full-size and see what floats your boat. That would be
convert a.tga b.tga -compose Atop -composite out.tga
Here is an Imagemagick command that does what you want:
convert -gravity Center whitecloud.tga -fx "u/max(u.a, 1/255)" bg.tga +swap -composite -fx "u*u.a" comp.tga
What's happening here?
-fx command #1: Convert whitecloud.tga from premultiplied alpha to "normal". The max() operator is a special case to avoid dividing by zero.
+swap command: Make bg.tga the first image and the revised whitecloud.tga the second.
-composite these two regular, non-premultiplied images.
-fx command #2: take the result, and return to a premultiplied alpha format.
This gives exactly the same result as After Effects.
Note that, as I wrote it, it only works for an opaque bg.tga. You'd need to do some extra work to handle a transparent background image.
If you want to duplicate the After Effects result, then I believe what you want to do in ImageMagick is the following -- composite the background image with a white image using the cloud as a mask:
convert bg.tga \( -clone 0 -fill white -colorize 100 \) whitecloud.tga -compose over -composite cloud_blue.tga
I have posted a JPG result, but my .tga result is the same.

Masking an image's alpha in Imagemagick

I need to create an image to be used as a rollover background image. It's a circular pattern that is split into 8 pieces. Here's a screengrab of the main image (png with transparency):
And here's a screengrab of the mask image. It's the same size as the main image and features 'pie' pieces in order to mask all but the sector that is being hovered over.
I'm including screengrabs, as I believe the answer should be pretty simple (aren't all answers simple when you know them?!) so I'll save bandwidth, but I can upload the original files if it's helpful.
Here's the command I'm using to create the new masked image:
convert main.png \( mask.png -colorspace gray -alpha off \) \
-compose copy-opacity -composite new.png
The trouble is that the new image created has flattened the original image's alpha to a black background:
How do I get Imagemagick to preserve the original png's transparency?
You want masked composition to do this. http://imagemagick.org/Usage/compose/#mask
The technique is to compose the original image (the src) onto a fully transparent image of the same size (the dst), using a mask to limit composition area (the mask). It is a special case of the -composite operator, and involves 3 images, rather than 2 like the rest of the compose methods. You don't specify any -compose mode for this.
A quick way to get the fully transparent dst that you need for this technique is to clone the src image and zero out its alpha channel, then swap the order of src and dst so that they are in the right order for the -composite operation to follow:
convert main.png -alpha on \( +clone -channel a -fx 0 \) +swap mask.png -composite out.png
I was not satisfied with retroj's solution as it seems to ignore the grayscale of the mask.
This one worked for me:
composite -compose Dst_In \( mask.png -alpha copy \) main.png -alpha Set PNG32:result.png
or
convert -compose Dst_In \( mask.png -alpha copy \) main.png -alpha Set -composite PNG32:result.png
Dst_In method multiplies the alpha channels of two images. The trick here is to convert the grayscale mask to an alpha channel for it which is done with -alpha copy.

Resources