I'm trying to combine 3 images using imageMagicks 7 latest version however the first layer is always missing.
convert "image_03.png" "image_02.png" "image_01.png" -background none -alpha set "product.psd"
However i only get two layers??
Attached are the images below ...
A PSD file expects a layer that is the flattened layer from all the other layers. It needs to be the first layer. Photoshop assumes the first layer is the flattened layer. It must be created in Imagemagick and combined with the other individual layers as the first image in the command sequence when writing a PSD file. So I create it last from clones and then insert it at the first position (0).
Try the following.
Unix syntax:
convert "image_03.png" "image_02.png" "image_01.png" \( -clone 0-2 -flatten \) -insert 0 -background none -alpha set "product.psd"
If on Windows, remove the \s from in front of the parentheses.
Reorder the images as desired for the layers in the PSD file.
Related
I have set of multiple images, which I need to merge in to one eps file as separate layer. Is it possible via ImageMagick? how?
You can overlay images with the -composite command, you can give it at shot:
$ convert image1.jpg image2.jpg ... imageN.jpg -composite output.esp
See https://imagemagick.org/script/composite.php
Suppose I have some image a.jpg and some other image b.jpg.
The desired output out.jpg should be obtained by copying all the pixels from b.jpg that are not black onto a.jpg, all other pixels shall remain untouched.
I tried using composite but had no success whatsoever.
EDITED TO ADD: A solution here can be quite simple and generic, but going forward, please remember to always include your version of ImageMagick and which OS or platform you're working on. There are some syntax differences that can make that important.
At the very simplest, using ImageMagick v6, you should be able to do something like this...
convert b.jpg -background none -transparent black a.jpg +swap -composite out.jpg
That reads in the B image, changes all the pure black pixels to transparent, then reads in the A image, swaps the images so they're in the right order, then composites the modified B image over the A image and writes the output.
You can add a fuzz value like "-fuzz 5%" ahead of the "-transparent" operation to expand the selection to include near-black pixels, also.
To use with IMv7 change "convert" to "magick".
Task: i have an input png file (many actually, but i'll just loop the solution). It is 16x16 PNG, 32bit with partial transparency along edges.
It so happens that toolbar of a certain stupid platform requires 17x17 files. My problem is that imagemagick kills transparency when doing simple transformations.
So:
Sanity check:
convert add.png PNG32:add_COPIED.png
creates another 16x16#32bpp file. So far so good.
Transformation (gravity is fine):
convert add.png -extent 17x17 PNG32:add_17.png
creates a file with solid white background. That's not good.
What doesn't work:
I tried a serious number of combinations of transparent, transparent-color, background, alpha and flatten. Got nowhere.
What does work:
convert address_book.png -alpha Extract address_book_MASK.png
convert address_book.png -extent 17x17 PNG32:address_book_17.png
convert address_book_MASK.png -background black -extent 17x17 address_book_MASK17.png
composite -compose CopyOpacity address_book_MASK17.png address_book_17.png PNG32:address_book_FIN.png
While i have a working set of commands and I can get through the day, I honestly believe that this is the wrong way to do things - four commands that create 3 intermediate files that i need to delete later. Surely it can be done in a better way?
Set the background colour before changing the extent:
convert input.png -background none -extent WxH result.png
Please help. Is there an easy way to take the largest layer of a tiff and zip compress it back as a single layer tiff again with imagemagick or similar?
Just a slightly easier version of Fred's answer. You can generate a list of the area (in pixels) of each layer in a TIF followed by the layer/scene number like this:
magick identify -format "%[fx:w*h] %s\n" image.tif
Sample Output
240000 0
560000 1
200000 2
So, if we do that again, sort it reverse numerically and take the second field of the first result, we will get the number of the layer with the largest area:
layer=$(magick identify -format "%[fx:w*h] %s\n" image.tif | sort -rn | awk 'NR==1{print $2}')
So, the complete solution would look like:
#!/bin/bash
# Get layer number of layer with largest area
layer=$(magick identify -format "%[fx:w*h] %s\n" image.tif | sort -rn | awk 'NR==1{print $2}')
# Extract that layer and recompress as single layer
magick image.tif[$layer] -compress lzw result.tif
If you are using ImageMagick v6 or older:
magick identify ... becomes identify ...
magick image.tif ... becomes convert image.tif ...
In concept, using ImageMagick this can be done in a single command. Here's an example...
magick input.tif -background none -virtual-pixel none ^
( -clone 0--1 +repage -layers merge ) ^
-distort affine "0,0 0,%[fx:s.w==u[-1].w&&s.h==u[-1].h?0:h]" ^
-delete -1 -layers merge output.tif
That starts by reading in the original TIF and setting the background and virtual-pixel settings to "none".
Then inside the parentheses it clones all the layers of the TIF, repages them, and merges them into a single image with the dimensions of the largest layer. That will become a gauge to measure with.
Next it uses "-distort affine" to slide each image out of the viewport and leave it transparent unless the image matches the width and height of that gauge. So after that distort, the largest image will remain unchanged, and all the others will be transparent.
Finish by deleting that gauge image and merging the rest. All the layers are transparent except the largest one, so merging them leaves just that visible one as a single layer.
The command is in Windows syntax using IM7. If you're using ImageMagick v6, use "convert" instead of "magick". To make it work in *nix, change the continued line carets "^" to backslashes "\" and escape the parentheses with backslashes "\(...\)". There may be other issues I've overlooked.
Obviously if there are two or more layers matching the largest dimensions, the output result will only be the first one from the original TIF.
Edited to add: This method will only work if both the greatest width and greatest height are on the same image.
How do you define largest? Width, Height, File size? If the largest dimension from width and height is used, then in Unix, you can do the following on a 3 layer tif file. Get the max dimension of each layer. Then find which layer is the largest. Then use just that layer when reading and writing the file.
Arr=(`identify -format "%[fx:max(w,h)]\n" img.tif`)
echo "${Arr[*]}"
500 1024 770
num=${#Arr[*]}
dim=0
for ((i=0; i<num; i++)); do
if [ ${Arr[$i]} > $dim ]; then
dim=${Arr[$i]}
index=$i
fi
done
echo "$index"
2
convert img.tif[$index] -compress zip newimg.tif
identify newimg.tif
newimg.tif[2] TIFF 770x768 770x768+0+0 8-bit sRGB 3662B 0.000u 0:00.000
I cannot think of any direct and simple method to find the largest layer and extract it in the same command line.
I am trying to figure out the best way to do this, since I need to create a script that will complete this task for about 3000 image files. So, I have two sets of images and I want to create two more sets. The object is to take the left vertical half of image A and combine it with the right half of image B, creating set AB. I will also need to do the opposite and create set BA, which would be the forth set. I need to do this in a way such that it continues the naming convention for the files, which have names like name.001.jpg. Any help will be much appreciated.
Here is an example of how to do that in ImageMagick Unix syntax for two images.
Image1:
Image2:
convert logo.jpg logo_b5.jpg -crop 50x100% \( -clone 0,3 +append +write logo_A.jpg \) \( -clone 2,1 +append +write logo_B.jpg \) null:
logo_A.jpg
logo_B.jpg
Please explain where your two sets of data are stored and how they are named. For multiple pairs of images, you will need to write a loop assuming you have each set with the same name in two different folders. But you need to say what OS you are using since Windows bat scripting is different from Unix shell scripting.