Creating a semi-transparent PNG with ImageMagick/convert - image

I have PNG files that I would like to convert the whole image to be semi-transparent.
The image will be referenced in a KML file as an icon overlay for use in Google Earth/Maps.
The following examples have been suggested to me using the ImageMagick convert command, however neither seems to work.
The first example results in an error,
$ /usr/local/bin/convert 121112142121.png -channel Alpha -evaluate Set 50% 2121112142121.png
convert: no decode delegate for this image format '121112142121.png' # error/constitute.c/ReadImage/550.
convert: option requires an argument '-evaluate' # error/convert.c/ConvertImageCommand/1400.
the second fails to make any observable change to the image:
convert filename.png -fill '#00000080' -draw 'matte 100,100 reset' output.png
While I can find many examples on the web for creating fully transparent images from specific colors or alpha masks, I cannot seem to find any that work for creating semi-transparent images or changing the opacity. I would like to find a way to do this with the convert command, or with ImageMagick Perl.
(ImageMagick version is 6.8.0-4)

Resolution has been found:
convert input.png -alpha set -channel A -evaluate set 50% output.png
The above command makes the entire image (all colors) semi-transparent.
Another problem I had was that the latest version of ImageMagick was compiled from source without all the most recent image libraries installed (in particular libpng). Pay close attention to the output of configure to ensure libpng is found if compiling from source. It also appears that versions of ImageMagick earlier than 6.6 and/or older versions of libpng may not support transparent png generation.

convert input.png -alpha set -channel A -evaluate Divide 2 output.png
Thank you #caw for pointing this out in your comment. This helps in the case where the image already has some transparent pixels. -evaluate set 50% ruins the already-transparent pixels that had alpha 0, setting their alpha to 50%, which is often not desirable.
-evaluate Divide 2 preserves the alpha, since fully transparent pixels are alpha 0, and 0 divided by 2 is still 0.

To followup on Tony Bogdanov's comment. If you already have fully transparent pixels you may want to use the following strategy:
Convert the transparent pixels into a mask
convert -alpha extract input.png mask.png
Perform the command listed in the answer above:
convert input.png -alpha on -channel a -evaluate set 65% output.png
Create a blank canvas the same size as the original image. Example:
convert -size 700x800 xc:none blankcanvas.png
Composite the semitransparent image and the blank canvas together using the transparent pixel mask
composite output.png blankcanvas.png mask.png -compose Src final_output.png

Related

How to change colors of an image using RGBA and more channels independently of their color

Since it is hard to me to explain what I'm trying to do, I'm gonna show you this page to show you what I'm trying to reproduce and understand:
https://optifine.net/showCape?colTop=FF0000&colBottom=00FF00&colText=0000FF&colShadow=FD0000
which outputs this:
and this one https://optifine.net/showCape?colTop=FF00FF&colBottom=0034EE&colText=000000&colShadow=FF00E2 outputs this:
You can modify the hexadecimal colors, basically I'm trying to reproduce something like that. Basically you modify the colors and it gives you an image at the end with the colors you used.
I've tried to make the "possible" template that could be used on the page on Photoshop which can be downloaded here, it is a .psd file, that's because of the Alpha Channel, which I'm not even sure if done correctly. But based of these RGBA channels it should be possible to change the color. Can be downloaded here: https://workupload.com/file/4xYkgQMk
So what I know so far is that there is a template with RGBA channel. Each channel is indepedent so it apperantly doesn't matter if it's RGBA and at the end R channel is used to turn into another color other than red, where I'm not sure about that.
I've asked the developer he told me that these channels get interpolated with the real color after that, probably the one you choose.
Basically what is happening at showCape? and its URL parameters is that, lets assume colTop got assigned to the red channel then when you put a color in colTop it will get a fixed color that it will encode or something.
So the template has 4 Channels RGBA that can be made in Photoshop, the white color 255,255,255 means basically full and the black 0,0,0 means complete black. Like that you can setup brightness scales for the template.
I just don't know how to modify the channels and I don't understand how to use the Alpha channels properly or set them up.
I'm also not sure in which programming languages it is possible to peform and if you can test the template directly in something like Photoshop. Is it possible to do it in JavaScript or something to easy setup and if not on what then, to test it fast?
Ok, so here's how you can generate that sort of thing with ImageMagick, which is included in most Linux distros and is available for macOS and Windows. Note that there are Python, PHP, node.js and other bindings available.
First, generate a red rectangle:
magick -size 200x150 xc:red red.png
Now see how to do the same thing with hex codes:
magick -size 200x150 xc:"#ff0000" red.png
Now, draw a red rectangle with a blue one on top:
magick -size 200x150 xc:red -fill blue -draw "rectangle 10,10 80,140" redandblue.png
Now make the blue transparent:
magick -size 200x150 xc:red -fill blue -draw "rectangle 10,10 80,140" -transparent blue redandtrans.png
Now make a gradient from lime green to magenta:
magick -size 200x150 gradient:lime-magenta gradient.png
Now overlay the red rectangle with transparent window onto the gradient:
magick gradient.png redandtrans.png -composite overlay.png
Now add text:
magick overlay.png -fill "#0000ff" -pointsize 16 -draw "text 90,40 'Coloured text'" result.png
And now do the whole thing again, in one go:
magick -size 200x150 gradient:lime-magenta \
\( xc:red -fill blue -draw "rectangle 10,10 80,140" -transparent blue \) \
-composite \
-fill "#0000ff" -pointsize 16 -draw "text 90,40 'Coloured text'" result.png
Now you have provided a template, I can separate out the channels with ImageMagick like this and append them side-by-side with Red channel on the left, then Green, then Blue then the alpha/transparency channel on the right. I also added a red box around each one so you can see the extent on StackOverflow's white background.
magick template.png -separate -scale 100x +append channels.png
Keywords: ImageMagick, absolute basics, tutorial, transparency, compose, overlay, command line, image processing.
this sounds like indexed colors / palette effect from the VGA days (like plasma, water and fire) Where you change the palette (in a specific way) and image changes with it.
The idea is that Your image/sprite does not contain RGB colors directly but color indexes from palette instead. Where part of the palette for your image/sprite contains a color gradient so gradients on image are also gradients on index (neighboring shades have also neighboring indexes). Many old pixelart sprites and images from the old days are done this way (sorted palette).
Now you can simply chose few colors in that part of palette and interpolate the rest of the gradient (linearly or better).
To mimic this your need:
have a indexed color pixel art with sorted palette
For example You can convert your image into BMP or GIF with palette and sort the colors.
detect the part of palette with color gradient
change/update the gradient
re-render or recolor image.

How to convert coloured Captchas to Grey Scale?

I'm trying to make a capcha solver, but I have ran into some trouble. The captcha that I am trying to solve has different coloured backgrounds.
I need to convert it to black text on white background so that it could easily be recognised by tesseract-ocr
I have tried
convert *.png -threshold 50% *.png which only shows some of the digits.
The problem with simple 50% thresholding is that both colours may be lighter than 50% grey and will therefore come out as white. Or, conversely, both colours may be darker than mid-grey and therefore bith come out as black.
You need to do a 2-colour quantisation to get just 2 colours, then go to greyscale and normalize so the lighter colour goes white and the darker one goes black. I am not near a computer, to test, but that should be:
convert input.png -colors 2 -colorspace gray -normalize result.png
Now, you will find some images are inverted (black on white instead of white on black), so you can either test the top left corner pixel and if it is white, then invert the image. Or, you could get the mean of the image and if it is more than 0.5 that would indicate that the image is largely white and therefore needs inverting.
Invert with:
convert input.png -negate output.png
Get top-left pixel with:
convert image.png -format '%[pixel:p{0,0}]' info:-
Get mean value with:
convert image.png -format "%[mean]" info:-

Merging two transparent gifs as layers

I've found this page on the imagemagick forum: Merging 2 gifs, one is animated and transparent which links to the imagemagick docs on Animation Modification; specifically, the example here:
convert canvas_prev.gif -coalesce \
-gravity NorthEast -draw 'image over 5,5 0,0 "rose:"' \
-layers Optimize draw_over.gif
Here's my attempt. I have these two gifs (i might be feeling a little morbid). The white in the first is actually transparent.
when I run
convert eyes.gif -coalesce -draw ' image over 0,0 0,0 "trump.gif" ' combine.gif
I get this:
which is not the complete effect I desire. The trump animation is no longer playing at all.
I want to see something more like this (this is created in Phaser JS, but this gives me no way to export the result as a new image other than manually recording a screencast):
One way to do it, yet not sure if it's the best, is as follows:
convert both animations into sprite-sheets of same dimensions
paste one image over the another
cut result into smaller frames and convert it into animated GIF
The commands should look like this:
montage -background none t.gif -tile x1# -geometry +0+0 tt.png
montage e.gif[0-16,0-9] -tile x1# -geometry +0+0 ee.png
magick convert -delay 10 -loop 0 ee.png tt.png -coalesce -flatten \
-crop 150x150 +repage output.gif
Tricky part is the second line with eyes image. It has only 17 frames while skull has 27. So the sprite sheet size must be adjusted.
I works, however I am not quite happy with this as solution requires manual entering of some parameters (frames selection and output image dimensions).

Making half an image transparent from the command line

I don't really know where to start with this one. I'm trying to do something that I thought would be relatively simple to accomplish with imagemagick, but I don't know the exact command to start with. I need to draw a line through an image, and then make everything above the line transparent in the image, and make everything below the line, the orignal image. What would be the best way to accomplish this using imagemagick?
So what I've come up with for now is to crop the image, and then resize it to the original size, but with a transparent background. The command I use is this, but it always comes out black. I'm not understanding why.
convert -background none -gravity south out.png -resize 400x200 -extent 400x400 result.png
Thanks for all of the help!
Here's a fairly easy way to do it. First, enable an alpha channel in case your image doesn't have one, then select the alpha channel for modification by the following -fx command. In there, if the current j is greater than half the height of the image, make the alpha layer opaque, else transparent. Easier than it sounds!
So, using this start image:
convert bean.jpg -alpha on -channel A -fx "j>h/2?1:0" result.gif
Or, the other way:
convert bean.jpg -alpha on -channel A -fx "j<h/2?1:0" result.gif
Or the other, other way:
convert bean.jpg -alpha on -channel A -fx "i<w/2?1:0" result.gif
Or, if you are feeling particularly silly on a Friday morning...
convert bean.jpg -alpha on -channel A -fx "hypot(i,j)/400-0.8" result.gif

RMagick: Setting opacity on a png that already has transparent elements

I need to compose images in rmagick. If I put a png that has transparent regions on another image and set the opacity of that png to 50% the parts that where transparent become white (with 50% opacity). But I want these regions to stay transparent.
Here's my code:
canvas = Magick::Image.new(1024,768)
canvas.opacity = Magick::MaxRGB
image = Magick::ImageList.new('/tmp/trans.png').first
image.background_color = "none"
image.opacity = Magick::MaxRGB/2
canvas.composite!(image, 50, 50, Magick::OverCompositeOp)
canvas.write('/tmp/composite.png')
Any suggestions?
After 8 hours of Googling I came across this post which allowed me to come up with the answer.
http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=19169
convert FileIn.png -channel a -evaluate Multiply 0.5 +channel FileOut.png
-channel a forces the selection of the alpha channel
-evaluate Multiply 0.5 modifies the transparency of the image
+channel changes the selection to include all of the channels in the output
And then to merge the two transparent png's and end up with a 3rd transparent png
(Please note I'm using GraphicsMagick for this operation instead of ImageMagick)
gm convert FileIn1.png FileIn2.png -background transparent -mosaic FileOut.png

Resources