Imagemagick commands to resize, rotate, wrap, and combine images - command

I'm currently using Photoshop to resize, rotate randomly, and wrap images randomly to create this type of montage....
Comic Covers
I got to thinking that kind of thing should be doable in Imagemagick. I know how to use all of the commands separately, and I can do random rotations and wraps using BASH, but getting a single image out of individual images is eluding me.
Assume that the source pictures are different sizes but should be resized to 250px wide. The images will be named image1.jpg, image2.jpg, etc. Also assume that the destination should be 1000x1000px. Depending on how many pictures I have, the whole 1000x1000 image may not be covered - I understand this. I mainly use BASH, but I have several different environments and shells available to me.

Using ImageMagick 6 or 7, if you have enough memory to read in all your images at once you can resize them, randomly rotate them, and place them all in random locations on a 1000x1000 canvas with a command like this...
convert granite: -duplicate 11 -resize 250x \
-background none -gravity center -extent 1000x1000 \
-distort SRT "%[fx:rand()*45-22.5]" -virtual-pixel tile \
-distort affine "%[fx:w/2],%[fx:h/2] %[fx:rand()*w],%[fx:rand()*h]" \
-flatten result.png
That uses the ImageMagick built-in image "granite:" duplicated 11 more times. Replace "granite: -duplicate 11" with a list of your input files.
It starts by resizing them all to 250 pixels wide, then placing them each in the center of a 1000x1000 transparent canvas.
The real work is done in the distort operations. First "-distort SRT" rotates each image a random amount between -22.5 and +22.5 degrees. Then the "-distort affine" relocates each image to a random location within the canvas. Any part of an image going beyond the canvas will be rolled back into the opposite side. That makes the result suitable for tiling.
This command flattens everything onto a transparent background wherever it might show between the images. Add "-background blue" just before the "-flatten" operation to change the background to blue, for example.
This works on my IM 6 in bash. For IM 6 in Windows change the continued line backslashes "\" to carets "^". For IM version 7 change "convert" to "magick".

Here is a bash Imagemagick 6 script that takes a list of images. You can replace it with your images. It uses subshell processing to avoid needing to write temporary images to disk. It saves the images in a miff: format as one file from the loop. Then it pipes the multipage miff: file to -layers merge, which overlays the images onto the 1000x1000 transparent base image. For Imagemagick 7, replace convert with magick.
list="lena.jpg barn.jpg mandril3.jpg zelda1.jpg"
convert -size 1000x1000 xc:none result.png
(
for img in $list; do
angle=`convert xc: -format "%[fx:round(-22.5+45*(rand()))]" info:`
xoff=`convert xc: -format "%[fx:round(1000*rand())]" info:`
yoff=`convert xc: -format "%[fx:round(1000*rand())]" info:`
#echo >&2 "angle=$angle; xoff=$xoff; yoff=$yoff"
convert "$img" -resize 250x -background none -rotate $angle -set page +${xoff}+${yoff} miff:-
done
) | convert result.png - -layers merge +repage result.png
If you have enough resources to hold all the images at once, then you can also do it in one command line as follows:
convert -size 1000x1000 xc:none \
\( lena.jpg barn.jpg mandril3.jpg zelda1.jpg -virtual-pixel none -background none \
+distort SRT "0,0 %[fx:250/w] %[fx:-22.5+45*rand()] %[fx:rand()*1000],%[fx:rand()*1000]" \) \
-layers merge +repage result.png

Cool, I'll try fmw42's script, but this is a script I came up with. It generates temporary files (which it deletes) and several convert commands, but it does work....
# Create blank montage...
convert -size 750x750 xc:black montage.jpg
for file in $(ls hall*.jpg | grep -v halloweencovers.jpg); do
echo $file
angle=$RANDOM; let "angle %= 32"; let "angle = angle - 16"; let "angle = angle * 5"
offsetx=$RANDOM; let "offsetx %= 75";let "offsetx = offsetx * 10"; offsetx="+$offsetx"
offsety=$RANDOM; let "offsety %= 75";let "offsety = offsety * 10"; offsety="+$offsety"
# Create blank image...
convert -size 750x750 xc:transparent blank.png
# create 250px image and rotate....
convert $file -resize 250x -alpha set -background none -rotate $angle out.png
# add 250px image to blank 750x750 canvas
convert blank.png out.png -composite output.png
# offset and wrap blank canvas with output image
convert output.png -roll ${offsetx}${offsety} output2.png
# merge montage with offset image
convert montage.jpg output2.png -composite montage.jpg
# clean up
rm -f out.png output.png output2.png blank.png
done

Related

How can I merge a signature and my module with an ImageMagick command?

I have this starting situation.
I have a jpg picture (A) with a module in which the signature slot is always in the same place.
I have also a signature (B) jpg picture, separated.
I use a program that allows external calls, but one single line only.
Is there an ImageMagick single command line command that allows me to do
Put Image (B) into image (A) at a specific x,y,height and width
Consider WHITE #FFFFFF as the alpha channel for image (B)
?
I am looking since a while now but haven't figured anything out.
Thanks
In ImageMagick, you would first make white transparent and then overlay B onto A. You need to use parentheses processing to keep the processes separate but in the same command line.
Unix syntax for ImageMagick 6:
convert imageA \( imageB -transparent white \) -geometry WxH+X+Y -compose over -composite result
or possibly
convert imageA \( imageB -transparent white -resize WxH \) -geometry +X+Y -compose over -composite result
Best if you provide your input images for demonstration.
See
https://legacy.imagemagick.org/Usage/basics/#parenthesis
https://legacy.imagemagick.org/Usage/compose/#compose
https://legacy.imagemagick.org/Usage/windows/

Create 24bit Bitmap with Imagemagick with special background color used for transparency

I am creating oldskool sprite images for an older gamedev software that loads 24-bit BMP only. The software detects the top left pixel color and makes it transparent on runtime.
I am trying to generate such BMP images with Imagemagick from transparent PNGs that I have, but I need the background to be lime #32cd32.
The following command in a batch file just makes a 24bit BMP file but the transparent areas appear black no matter what.
convert %1 -format bmp -type truecolor -background lime BMP3:"out.bmp"
Use the "-flatten" option:
convert $1 -background "#32cd32" -flatten BMP3:out.bmp
This composites the transparent image against the specified background color.
In ImageMagick, "lime" is saturated green (#00ff00). If you want #32cd32 use ' -background "#32cd32" '
Hard to estimate the issue without seeing the image, bit I would expect the alpha needs to be removed & replaced by the background color.
convert %1 -format bmp \
-type truecolor \
-alpha Remove \
-background lime \
BMP3:"out.bmp"
See "Alpha Remove" section.
The "-alpha Remove" method (added to IMv6.7.5) is designed to remove the transparency from an image, using the current "-background".

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.

Imagemagick command line, combine two different sized images

I'd like to use "convert" (or whatever) from Imagemagick to combine two different sized images. I'd like them to be aligned at the bottom left corners. For example, I have two images:
trans_alpha.png (a transparent 42x37 blank image)
and shadow.png (a 68x23 image, which I want overlaid on trans_alpha.png aligned at the bottom left)
The result I'd like would be a 68x37 image, NOTE these sizes are examples only, I don't want to put the size into the command line, I just want to use the sizes from the input images.
I have tried a lot of combinations without success:
Attempt no. 776 (close, but aligned to top left, not bottom left)..:
convert trans_alpha.png -background none shadow.png -gravity SouthWest -layers merge +repage result.png
Attempt no. 841 (aligned correctly, but result image isn't wide enough)...
convert trans_alpha.png shadow.png -gravity SouthWest -composite result.png
Hopefully that makes sense.
Thanks,
Paul
In answer to my own question (courtesy of the clever people on www.imagemagick.org)
convert \
trans_alpha.png shadow.png \
-flip \
-background none \
-mosaic \
-flip \
result.png
Imagemagick includes many useful transformations, but occasionally still it lacks the one you need. Since your original images are PNG lossless bitmaps, you can convert both to long-form PBM or a related format like long-form PPM. The advantage of these forms is that they represent the entire image, pixel by pixel, in plain text, which one can write a program -- usually a fairly short program -- to process any way one likes. As storage formats, PBM and PPM are egregiously inefficient, but they are likewise egregiously easy to manipulate, and that's what you want.
The pbm(5) manpage (available for example on Debian/Ubuntu systems in the netpbm package) is well written and explains the process clearly.
I am unable to test at the moment but you can use -page with layers so something like this might work but you may need to calculate the Y offset:
convert \
trans_alpha.png \
-background none \
shadow.png \
-page +0+10 \
-layers merge \
+repage \
result.png
You may not need the -background none

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.