I am trying to insert image into another image with ImageMagick. I want to do it in batch mode.
/images_to_insert/1.jpg 2.jpg 3.jpg 4.jpg...
/background_images/1.jpg 2.jpg 3.jpg
I am using this command:
composite images_to_insert/1.jpg -gravity center background_images/1.jpg results/result-%d.jpg
It works fine for one image, how to do it in batch mode for whole images? I tried this command without a luck:
composite images_to_insert/*.jpg -gravity center background_images/*.jpg results/result-%d.jpg
for i in images_to_insert/*
do
composite $i -gravity center background_images/$(basename $i) results/result-$(basename $i)
done
Related
I'm assuming ImageMagick is the best option for this, but please let me know if you have other recommendations that can be scripted.
I am trying to replace all the 32x32 tiles of an image with a single tile. This is an example for the original image:
This is the tile that I want to use to replace all tiles on the original image:
And this is what I want the output to be:
I've figured out from other posts on Stack Overflow that I can use ImageMagick's composite option to overlay the tile onto the original image:
$ convert original.png tile.png -composite overlay.png
Resulting in the following:
And I assume by knowing the original images dimensions I can overlay the tile manually multiple times. But is there a way to automate the process. In the example pictures I have given, I need to overlay the tile 8 times on the original 64x128 image.
How can I do this with ImageMagick or another software? And if ImageMagick, would the montage or composite command be a better option?
Edit: As an additional question, would it be possible to skip tiles that are completely transparent?
Input example:
Output example:
It isn't really important to be able to do this part, but would be nice.
If the tile image fits evenly into the dimensions of the original, a command like this should do most of what you want...
convert original.png tile.png -background none -virtual-pixel tile \
-set option:distort:viewport %[fx:u.w]x%[fx:u.h] -distort SRT 0 +swap \
-compose copyopacity -composite overlay.png
That reads in both images. Then it creates another canvas the size of the original and filled with multiple copies of the tile image. Then it uses the original as a transparency mask to create a copy of the new tiled image with the same transparent cells as the original.
I don't know why you would need to overlay the 8 tiles on the original. Just create it from scratch and name the output the same as your original
You could use Imagemagick montage to do that (unix syntax):
nx=`convert original.png -format "%[fx:w/32]" info:`
ny=`convert original.png -format "%[fx:h/32]" info:`
num=$((nx*ny-1))
montage tile.png -duplicate $num -tile ${nx}x${ny} -geometry +0+0 result.png
Here I use convert to duplicated the tile, but it uses a relatively current -duplicate feature. If you do not have a current enough version of Imagemagick, then just repeat the tile in montage as follows:
montage Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png Ro1Lp.png -tile 2x8 -geometry +0+0 result.png
As Fred (fmw42) says, "why don't you just create the whole image from scratch?".
Maybe your description isn't complete, so here are a couple more pieces that might help you work it out.
Given bluetiles.png and singlered.png:
you can position red ones as you wish like this:
convert bluetiles.png \
singlered.png -geometry +0+32 -composite \
singlered.png -geometry +32+96 -composite result.png
Given bluewithtransparent.png:
you can copy its transparency to the newly-created image like this:
convert bluetiles.png \
singlered.png -geometry +0+32 -composite \
singlered.png -geometry +32+96 -composite \
\( bluewithtransparent.png -alpha extract \) -compose copyopacity -composite result.png
I am trying to make a fast convert of a batch of files like this:
convert ./src/*.png -set filename: '%t' -gravity West -draw 'image over 0,0 424,600 "./panel.png"' ./dest/%[filename:].png
which is pretty similar to COMPOSITE:
convert ./src/*.png ./panel.png -set filename: '%t' -gravity +0+0 -composite ./dest/%[filename:].png
except the last one is not working and just making one first crappy-looking file.
Looks like it's bug?
Does anybody know how to make it more correct with -composite?
for|awk|ls|find for each file in shell is not acceptable - because that is slower than the first example.
Read in the list of files,
set their output filenames,
include the IM special image placeholder "null:",
read in your overlay image,
optionally, set the geometry,
and composite that overlay onto all the other images with "-layers composite".
That null: separates the original input file list from the overlay image so ImageMagick knows where in the stack you want to start doing the composite.
Try something like this (one step per line for readability):
convert ./src/*.png \
-set filename: '%t' \
null: \
./panel.png \
-layers composite ./dest/%[filename:].png
You could use Imagemagick mogrify command. See http://www.imagemagick.org/Usage/basics/#mogrify and http://www.imagemagick.org/Usage/basics/#mogrify_compose
cd to input directory
mogrify -format png -path ./dest -gravity West -draw 'image over 0,0 424,600 "./panel.png"' *.png
Looks like it's bug?
Not a bug. Your second command is telling ImageMagick to consume all files matched into an image stack, and composite it as one.
You can attempt the same solution with the mogrify utility, but I believe it would be way simpler if you expand the bash script with a single for loop.
for f in $(ls src/*.png)
do
dest=$(basename $f);
convert "$f" ./panel.png -gravity West -composite "./dest/$dest"
done
I am using mogrify utility to batch converting images and preparing them for web.
Bumped with a question how to do watermark using same mogrify utility. There are a lot of examples with how to watermark but all of them using composite utility. It is not suitable for me as I dont want to split process into two steps.
Here is a simplified command line
mogrify -resize 400x400 -tile WATERMARK_FILE.png -path out\ input.jpg
it is do resize but does not compose with watermark
UPDATE:
Unfortunately its inpossible to do it by single step (via morgify). Although morgify accepts the -tile parameter it result to nothing. Probably its is a bug, because image to tile is read from disk but not used.
I solved the task by separately preparing watermark tiled image by size equalent or bigger then destination images.
:: prepare emty transparent image with size %IMG_SIZE%
convert -size %IMG_SIZE% xc:none "%WATERMARK_BASE_FILE%"
:: tile watermark on it
composite -dissolve 30 -tile "%WATERMARK_FILE%" "%WATERMARK_BASE_FILE%" "%WATERMARK_TILED_FILE%"
:: resize images and draw watermark on each image
morgify -resize %IMG_SIZE% -gravity center -draw "image src-over 0,0 0,0 '%WATERMARK_FILE%'" -path "%DST_DIR%" "%SRC_MASK%"
I have around 100 pictures that i want to add white border to it all at once.
I use Linux and also use gimp ,.. please suggest me something to do so online of offline.
and one more thing that i have tried convert option on imagemagick but nothing happen.
If you want to do 100 all at once you will be best off using ImageMagick's mogrify command like this to add a 10 pixel white border around all images:
mogrify -mattecolor white -frame 10x10 image*.jpg
If the images are not all in a single directory, you can do the following which will do the same thing across all subdirectories of the one you are currently in:
find . -name \*.jpg -exec convert "{}" -mattecolor white -frame 10x10 "{}" \;
Obviously you can change the 10 to a different number of pixels if you wish.
Please make a backup before using this as I may have misunderstood your needs.
Updated
If you want a drop shadow, you really need to be working with PNG rather than JPG since the former supports transparency and the latter doesn't - but IM can convert your JPEGs to PNGs anyway. I use the following command for drop shadows:
convert image.jpg \( -clone 0 -background black -shadow 80x3+0+8 \) -reverse -background none -layers merge +repage image.png
So, I would apply that to a pile of images like this:
#!/bin/bash
for f in *.jpg; do
new=${f%%jpg}png # Work out new name = original name minus "jpg" + "png"
echo Processing $f into $new
convert "$f" \( -clone 0 -background black -shadow 80x3+0+8 \) -reverse -background none -layers merge +repage "$new"
done
I have several images with different sizes.
1.jpg
2.jpg
3.jpg
I need to arrange them on 1 layout in the following order:
1st image in the top-left corner
2nd in the middle
3rd in the middle
(as in the example: http://postimg.org/image/4wcf5l0gl/ )
I try smth like:
montage 1.jpg 2.jpg 3.jpg -mode concatenate -tile 1x3 out.jpg
but 2nd and 3rd appear on the left side.
You can easily do this with the convert program by a sequence of -append operations. In the simplest case:
convert 1.jpg 2.jpg -append 3.jpg -gravity center -append out.jpg
Note that order of operations goes from left to right with convert. I load two images, and append them together. Then I load image #3 and change the -gravity setting to center, to perform a centered append (instead of a "left justified" one). Last is the output filename.
You can add the text at the top by generating a label and putting a horizontal append (+append) in its proper place in the sequence:
convert 1.jpg label:'text from file-name' +append 2.jpg -append 3.jpg -gravity center -append out.jpg
To pad the images with space around them, use -border on each individual image before appending. You can use grouping parentheses to limit the effect of any operation to only certain images*:
convert 1.jpg label:'text from file-name' -bordercolor white -border 10 +append \( 2.jpg -border 10 \) -append \( 3.jpg -border 10 \) -gravity center -append out.jpg
You can get more and more elaborate from here. Just remember that order of operations proceeds from left to right, and operations can be limited to certain images by use of grouping parentheses.
*footnote: The syntax of the commands above assume a typical unix/linux shell environment. The syntax will have to be adapted if you are using some other environment.