Image Magick: convert and composite in one command - command-line

I am currently working on a automation script to convert imgaes for use on websites. Every image gets a white and black border and is combined with a prepared alpha channel image. The black border (outer border) combined with the alpha channel will look like a shadow when everything is done.
I've got the following files:
test.jpg (the test image)
test.tga (the alpha channel)
And I convert the input image in 2 steps:
convert test.jpg -bordercolor #FFFFFF -border 15 -bordercolor #000000 -border 30 test.png
(adds the white and black border to the image and saves as 'test.png')
composite -compose CopyOpacity test.tga test.png test2.png
(joins image file with alpha channel from test.tga and saves as test2.png)
So now my question is: Is there any way to invoke both steps as one command? I know that convert also supports the -compose options, if I got that right from the manual, but I could not get it working. It would be best, if I could edit and join the image with the alpha channel with one command. (Command will be executed from my Application and I don't want to execute many sub-processes)
Maybe someone knows a solution for this.
Thanks in advance!

Related

Alter a person's race from the command line.

A disability project I'm building (here for your interest). Uses a set of copyright-free icons. Here are some examples of them in use.
It's bothering us that all of the icons are of white people. We'd like to make them more diverse and representative.
The icons are pngs. Here's an example. I feel like there must be a command line way of replacing one colour with another. If I had that, then I could do a lot of things semi-automatically, but I have NO idea if such a thing is possible.
Is it?
You can replace a specific color with another using ImageMagick or GraphicsMaqick. In your screenshot, the "flesh" is color #FFEFC6. Use -fill newcolor -opaque oldcolor to replace this color with another (and use "-fuzz 10%" to replace all pixels whose color is "close" to oldcolor):
magick pdzSe.png -fill black -fuzz 10% -opaque "#FFEFC6" black.png
magick pdzSe.png -fill orange -fuzz 10% -opaque "#FFEFC6" orange.png
magick pdzSe.png -fill brown -fuzz 10% -opaque "#FFEFC6" brown.png
If you want to use GraphicsMagick, replace magick with gm convert, and if you want to use ImageMagick version 6, replace magick with convert. If you're running on Windows, you'll need to replace the % with %%.
This should be enough to get you started, but it's a crude solution that doesn't account for blended pixels such as those appearing in your sample "thumbs-up" icon. Below are the results of running the same commands against "thumbs-up", enlarged 4x so you can see the "halo" effect around the edges of the "flesh". Getting rid of the "halos" will require more work, specific to your icon set. Ideally you'd have the original vector art-work to update, but I suppose that's not the case.
In fact, the original artwork is available at straight-street.com (search for "good") and working with the original SVG files is much simpler; there is no "halo" issue. Here I just used a text editor to change the color FFEFC6 to FF8888:

Dividing Ground-penetrating radar profile through image processing

Please look at the attached image. It is a GPR profile and using image processing techniques, I am trying to divide this image into 3 zones by labeling with colors the whole image on the top:
when parabolas in the image are very clear and distinct with high pixel values - green zone/ line at the top
when parabolas in the image are blurred but visible - yellow zone
when parabolas are distorted or when not parabolas are present - red zone
What techniques should I use? What's the best approach to solve it?
I have tried various techniques but not with success in every case, because, as you can in the following image, sometimes the parabolas are too close to one another and identifying them is becoming an issue.
A sample of how I want to zone it: https://www.dropbox.com/s/9zm9epgf0gt7591/sample.png?dl=0
One of the tried code: simplest one.
clear all
clc
%read png image
H=imread ('origpng.png');
%convert to gray scale
I = rgb2gray(H);
I(I>150)=0;I(I<100)=0;
figure,imshow(I)
J=I;
J=255-J;
figure, imshow (J)
J(J<255)=0;
figure,imshow (J)
Your question is not very clearly posed, but I spent some time on it and felt like sharing my thoughts. I am not preteding for an instant that this is anywhere near a complete, or rigorous answer - just some musings that might give you some ideas. Also, I use ImageMagick, but if you have and know Matlab, you should use that - I am not suggesting you switch tools.
First, I did a Canny Edge detection like this:
convert http://i.stack.imgur.com/XITAE.png -canny 0x1+15%+50% canny.jpg
that gives me this:
I then "squash" that down till it is just 1 pixel high, which effectively totals up and averages all the columns - I make it 10 pixels high here so you can see it. Where it is white, there are lots of parabolas, elsewhere there are fewer.
Then I stretch that back up to the full height of the original image and blur it a bit - note that everything up to the following image is just one line of "code":
convert http://i.stack.imgur.com/XITAE.png -canny 0x1+15%+50% -resize x1! -normalize -resize 827x310! -blur 0x11 -colorspace gray mask.png
I then use the above as an opacity mask for a red image the same size as your original like this:
convert -size 827x310! xc:red mask.png -compose copy-opacity -composite colouredmask.png
Then I took your original image and coloured it with yellow like this by first creating a yellow image and then blending it onto your image and then I blended the red image from above on top of that:
convert -size 827x310! xc:yellow yellow.png
convert http://i.stack.imgur.com/XITAE.png yellow.png -compose colorize -composite colouredmask.png -compose overlay -composite result.png
giving
Obviously you can set different parameters and use different thresholds and things, but it kind of heads towards the sort of thing you are aiming it.
So the entire process is:
# Make mask of peaky areas - line 1
convert http://i.stack.imgur.com/XITAE.png -canny 0x1+15%+50% -resize x1! -normalize -resize 827x310! -blur 0x11 -colorspace gray mask.png
# Colour mask with red - line 2
convert -size 827x310! xc:red mask.png -compose copy-opacity -composite colouredmask.png
# Tint original image with yellow and then overlay semi-transparent red area
convert -size 827x310! xc:yellow yellow.png
convert http://i.stack.imgur.com/XITAE.png yellow.png -compose colorize -composite colouredmask.png -compose overlay -composite result.png
Notes
Squashing pixels... sorry for confusing you with my terminology! Basically, when I squash the pixels down to a single row, you need to imagine dropping a brick on the top of the image and flattening it down to just one pixel tall. So, essentially, you draw an imaginary line underneath the image and then you work across the image totalling up the number of WHITE (i.e. edge) pixels in each vertical column. Columns that have more white pixels will add up to larger numbers. Columns that have no white pixels will add up to zero. Once you have got the totals for each column, you find the highest total - let's say it is 32 and then you multiply all totals by 255/32 so that everything is normalized to 255, or white. Now the squashed strip represents the edge energy in each column. And I then use that as the opacity for the red when I overlay - so columns with more white edges in the Canny image will show up with more red in the result.
Let's demo what happens if I squash down to 10 pixels wide and 1 pixel high before scaling back up to the original size - basically it means that my resulting mask will have only 10 possible values (or columns) columns and that each column will be a single constant brightness. I'll put the Canny image underneath so you can see that the brightness of the squashed strip represents the edge energy:
convert http://i.stack.imgur.com/XITAE.png -canny 0x1+15%+50% -resize 10x1! -normalize -scale 827x310! mask.png
If you want to introduce another colour, you need to work out what your algorithm is for controlling where that colour should appear. You then do exactly the same thing again - you make a mask that is light where you want that colour in your output image and dark where you don't want that colour. Then you use that mask as the opacity for your new colour (as I did at the line labelled line 2 above) and then you overlay it like I did in the last line of my code above.

Replace transparency in PNG image with white background

I have a PNG image with an alpha channel (i.e. transparency), and I need to create versions with the image layer composed onto a white background. I want to use a scriptable command using a CLI tool such as Image Magick to directly convert PNG to PNG losslessly.
An example of a non-working Image Magick command which results in an error is:
convert input.png -background white -flatten output.png
-background white -alpha remove -alpha off
Example:
convert image.png -background white -alpha remove -alpha off white.png
Feel free to replace white with any other color you want. Imagemagick documentation says this about the -alpha remove operation:
This operation is simple and fast, and does the job without needing
any extra memory use, or other side effects that may be associated
with alternative transparency removal techniques. It is thus the
preferred way of removing image transparency.
This works for me:
convert -flatten img1.png img1-white.png
Documentation references:
-flatten command-line option
-layers command-line option (-flatten is equivalent to -layers flatten)
Flattening image and applying background image is straight forward in ImageMagick
However, order of the commands is very important
To apply any background on a transparent image and flatten it, first apply the background than flatten it. The reverse doesn't work.
$ convert sourceimage.png -background BackgroundColor -flatten destinationimage.png
The only one that worked for me was a mix of all the answers:
convert in.png -background white -alpha remove -flatten -alpha off out.png
here's how to replace the same image in all folders in a directory with white instead of transparent:
mogrify -background white -flatten */*.png
Using -flatten made me completely mad because -flatten in combination with mogrify crop and resizing simply doesn't work. The official and for me only correct way is to "remove" the alpha channel.
-alpha remove -alpha off (not needed with JPG)
See documention: http://www.imagemagick.org/Usage/masking/#remove
The Alpha Remove section of the ImageMagick Usage Guide suggests using the -alpha remove option, e.g.:
convert in.png -background white -alpha remove out.png
...using the -background color of your choosing.
The guide states:
This operation is simple and fast, and does the job without needing any extra memory use, or other side effects that may be associated with alternative transparency removal techniques. It is thus the prefered way of removing image transparency.
It additionally adds the note:
Note that while transparency is 'removed' the alpha channel will remain turned on, but will now be fully-opaque. If you no longer need the alpha channel you can then use Alpha Off to disable it.
Thus, if you do not need the alpha channel you can make your output image size smaller by adding the -alpha off option, e.g:
convert in.png -background white -alpha remove -alpha off out.png
There are more details on other, often-used techniques for removing transparency described in the Removing Transparency from Images section.
Included in that section is mention of an important caveat to the usage of -flatten as a technique for removing transparency:
However this will not work with "mogrify" or with a sequence of multiple images, basically because the "-flatten" operator is really designed to merge multiple images into a single image.
So, if you are converting several images at once, e.g. generating thumbnails from a PDF file, -flatten will not do what you want (it will flatten all images for all pages into one image). On the other hand, using the -alpha remove technique will still produce multiple images, each one having transparency removed.
It appears that your command is correct so the problem might be due to missing support for PNG (). You can check with convert -list configure or just try the following:
sudo yum install libpng libpng-devel
This is not exactly the answer to your question, but I found your question while trying to figure out how to remove the alpha channel, so I decided to add this answer here:
If you want to remove alpha channel using imagemagick, you can use this command:
mogrify -alpha off ./*.png
Welp it looks like my decision to install "graphics magick" over "image magick" has some rough edges - when I reinstall genuine crufty old "image magick", then the above command works perfectly well.
edit, a long time later — One of these days I'll check to see if "graphics magick" has fixed this issue.
I needed either: both -alpha background and -flatten, or -fill.
I made a new PNG with a transparent background and a red dot in the middle.
convert image.png -background green -alpha off green.png failed: it produced an image with black background
convert image.png -background green -alpha background -flatten green.png produced an image with the correct green background.
Of course, with another file that I renamed image.png, it failed to do anything. For that file, I found that the color of the transparent pixels was "#d5d5d5" so I filled that color with green:
convert image.png -fill green -opaque "#d5d5d5" green.png replaced the transparent pixels with the correct green.
I saw this question and answers which really help me but then I was needed to do it for a lot of files, So in case you have multiple images (PNG images) in one folder and you want to do it for all:
find ./ -name "*.png" -exec convert {} -flatten {} \;
this creates an image just placing the 1st with transparency on top of the 2nd
composite -gravity center ImgWithTransp.png BackgroundSameSizeOfImg.png ResultImg.png
originally found the tip on this post
To actually remove the alpha channel from the file, use the alpha off option:
convert in.png -background white -alpha off out.png
Tried all, none worked. This one did:
convert input.png -channel rgba -alpha set \
-fill none -opaque white \
-fill white -opaque black \
-fill white -opaque none \
-alpha off output.png
It's -alpha off, NOT -alpha remove! iOS app store upload fails when there is an alpha channel in any icon!!
Here's how to do it:
mogrify -alpha off *.png
This does the job for me:
magick convert OLD.png -background white -alpha remove NEW.png
Here is a starter image with a transparent background in case it helps with testing:
Also, for one-offs on PC, you can always open the PNG file in Windows Paint and click Save. This will automatically turn the transparency to opaque white.

How to change background color of an eps file while converting it to jpeg or png

I am converting eps (Encapsulated PostScript) files to jpeg files with ghostscript. A sample command I use is:
gswin32.exe -sDEVICE=jpeg -dJPEGQ=100 -dNOPAUSE -dBATCH -dSAFER -r600x600 -dGraphicsAlphaBits=4 -dUseCIEColor -dEPSCrop -sOutputFile=”a.jpeg” b.eps
The input eps files come with white backgrounds (I only have their clipping path). What I need to do is change this white background to another color in the output images, or it would be even better if I could make them transparent (output file format would be png). How can I do this?
never tried it myself but you should be able to convert your eps file into png by setting:
-sDEVICE=pngalpha
also the pngalpha device has a -dBackgroundColor option:
-dBackgroundColor=16#RRGGBB (RGB color, default white = 16#ffffff) For
the pngalpha device only, set the
suggested background color in the PNG
bKGD chunk. When a program reading a
PNG file does not support alpha
transparency, the PNG library converts
the image using either a background
color if supplied by the program or
the bKGD chunk. One common web browser
has this problem, so when using on a web page you
would need to use
-dBackgroundColor=16#CCCC00 when creating alpha transparent PNG images
for use on the page.
more details here: Details of Ghostscript output devices see section 3.1. PNG file format
After you've obtained your (white background) images from Ghostscript, you could use ImageMagick's convert or GraphicMagick's gm convert commands to change the white to transparent background:
convert -background transparent my.png my_transp.png

How to create semi-transparent image using imagemagick

I have a hex (i.e. #FF0000) color and want to generate 50% transparent 50x50 image using imagemagick from command line.
I had to figure out something similar when I was working with CSS 3 and RGBA.
convert -size 50x50 xc:'rgba(255,0,0,0.5)' red_0.5_pixel.png