imagemagick compose one transparent png(as mask) with one jpg - imagemagick

I have 2 type of images.
Some hundreds of png images with just one color(gray) and some transparent zones then must be transparent even in final result.
Over 30 thousands of jpg images with many size.
I must estrapolate from jpg images the gray zones of png files.
Now i use something like this :
convert JPG_FILE.jpg -resize WIDTH_OF_PNGxHEIGHT_OF_PNG^ -gravity Center -crop WIDTH_OF_PNGxHEIGHT_OF_PNG+0+0 -alpha Set PNG_FILE.png ( -clone 0,1 -alpha Opaque -compose Hardlight -composite ) -delete 0 -compose In -composite RESULT_IMAGE.png
it works very good but its a bit slow
any suggestion for faster execution?

Related

imagemagick montage: insert images of different sizes

I have an image a.png of size 800x600, and two images b.png and c.png of size 400x300 each. I want to montage (insert) the three images without size changes into a png image of size 800x900, such that a.png is at the top, and b.png and c.png side-by-side underneath.
How can I do this with imagemagick convert or montage?
Generate sample images, 1/10th the real size:
magick -size 80x60 -background red -gravity center label:"A" a.png
magick -size 40x30 -background lime -gravity center label:"B" b.png
magick -size 40x30 -background blue -gravity center label:"C" c.png
Now, you can load A, and inside parentheses, load B and C and place side-by-side as a new image, then append that result below A:
magick a.png \( b.png c.png +append \) -append result.png
Or, if you dislike the parentheses, you can join B and C side-by-side into a single image, load A, swap the order so A is at the top and then append the combined image below:
magick b.png c.png +append a.png +swap -append result.png
Note the distinction between:
+append meaning "append to the right", and
-append meaning "append below".
Note that, in addition to +append and -append, there are the newer tools called +smush and -smush which do exactly the same but take a parameter which is the number of pixels to offset the appending. So if you do +smush 5 it will do the same as +append but leave 5 pixels of background colour showing in the new gap between the images. If you use a negative offset, it will append in the same place but overlap the two images by the offset.
Here's an example, I make the background magenta and smush B and C with a 10 pixel gap. Then change the background to yellow before smushing the result below A with a 15 pixel offset.
magick -background magenta b.png c.png +smush 10 a.png +swap -background yellow -smush 15 result.png
If still using v6 ImageMagick, replace magick with convert.

How to split an image with a grid and preserve transparency bounding box

I have some png images that I want to split it into parts, like by grid or size.
But each part should have the same bounding box (transparency) as original image.
Example:
Splitting image into 2 parts.
Original: 200 × 89
Output:
part_1.png, 200 × 89
part_2.png, 200 × 89
Can ImageMagick do this? Or any other app or method.
My actual goal is to split into 100+ slices images.
EDIT:
Another goal to have an indents for each slice. Say indent = 10px.
Example:
Input: 200 x 100
Output:
part_1.png, 200 x 100
part_2.png, 200 x 100
And just as example, to visually compare input and output: combined output images in Photoshop as layer added one onto another
200 x 100 :
Also this is showing input image added onto combined(so it's better to see what was cropped and how):
In ImageMagick, you can split an image into many parts with the -crop command. For your example above with two parts, you can do that with the following commands. ImageMagick will append -0, -1 ... to the output file names.
ImageMagick 6:
dim=`convert image.png -format "%wx%h" info:`
convert \( -size $dim xc:none \) null: \( image.png -crop 50x100% \) -layers composite result.png
ImageMagick 7:
magick \( image.png -set option:dim "%wx%h" -crop 50x100% \) null: \( -size "%[dim]" xc:none \) -reverse -layers composite result.png
The results are:
See
http://www.imagemagick.org/Usage/crop/#crop
http://www.imagemagick.org/Usage/crop/#crop_percent
http://www.imagemagick.org/Usage/crop/#crop_tile
http://www.imagemagick.org/Usage/crop/#crop_quad
http://www.imagemagick.org/Usage/crop/#crop_equal
http://www.imagemagick.org/script/command-line-options.php#layers
Note that -crop keeps the virtual canvas information if you do not add +repage afterwards. So to put the individual images back into their original placement, you have to composite them onto a transparent background the size of the input. That is done in one command using -layers composite using the null: separator.
Here is another way to add transparent areas between parts of a crop in ImageMagick. Crop the image into pieces, chop off the parts you want to remove, then pipe to montage to add the spacing back.
Input:
Here I make this into a 4x4 grid of images with 10 pixel spacing:
convert lena.png -crop 25%x25% +repage -gravity east -chop 10x0 -gravity south -chop 0x10 +repage miff:- | montage - -background none -tile 4x4 -geometry +5+5 result.png
To answer your new question, you can do that with a script loop. On a Unix-like platform, assuming your images do not have spaces, you can do the following:
cd path/to/current_folder
list=`ls *.png`
for img in $list; do
name=`convert $img -format "%t" info:`
dim=`convert $img -format "%wx%h" info:`
convert \( -size $dim xc:none \) null: \( $img -crop 50x100% \) -layers composite -scene 1 path/to/new_folder/${name}_%d.png
done
If you want leading 0s in the output, say 3, use path/to/new_folder/${name}_%03d.png.
Note that to start with 1 rather than 0, I have added -scene 1.
Sorry, I do not know how to script for Windows.
Please always provide your ImageMagick version and platform.
In ImageMagick, the best way to put transparent areas into your image is with a binary mask that is put into the alpha channel of your image.
convert input.png \( -size 200x89 xc:white -size 10x89 xc:black -gravity center -composite \) -alpha off -compose copy_opacity -composite result.png
You can add as many blank areas as you want by adding more white areas to the mask or by tiling out one region of black and one region of white to create the mask with regular spacing of black and white.
Edited to add this ImageMagick 6 example which splits the input image into 4 pieces, 25% of the original width and 100% of its height, then creates a transparent canvas for each piece the same dimensions of the input image, and locates the pieces at their original offsets on those canvases.
convert input.png -set option:distort:viewport %[w]x%[h] -crop 25x100% \
-virtual-pixel none -distort affine "0,0 %[fx:s.page.x],%[fx:s.page.y]" out%03d.png
The output file names will be numbered starting from zero like "out000.png", etc.
Original message...
Here's a simple command using ImageMagick 7 that can crop an image into any number of pieces, and output all the pieces at their original offsets on transparent backgrounds of the original input dimensions...
magick input.png -crop 100x1# -background none \
-extent "%[fx:s.page.width]x%[fx:s.page.height]-%[fx:s.page.x]-%[fx:s.page.y]" out%03d.png
That "-crop 100x1#" tells it to split the image into a grid 100 pieces wide by 1 piece high. You could just as well specify the crop sizes as percents or numbers of pixels.
Edited again to add:
This following command will split the input image into the individual pieces specified with the "-crop" operator, then shave 5 pixels from every side of each piece, then apply a 5 pixel transparent border to every side of each piece. It will still remember the original locations of the pieces within the input canvas, so the "-distort affine ..." can extend the canvases and place the pieces where they were in the input image.
convert input.png -set option:distort:viewport %[w]x%[h] \
-bordercolor none -background none -virtual-pixel none \
-crop 25x100% -shave 5x5 -border 5x5 \
-distort affine "0,0 %[fx:s.page.x],%[fx:s.page.y]" out%03d.png
To use this command with IM7 you need to change "convert" to "magick".
Given the changes of requirements provided by Kamikaze, here is one way to achieve the split with indent in ImageMagick, assuming I understand correctly.
dim=`convert image.png -format "%wx%h" info:`
convert \( -size $dim xc:none \) null: \( image.png -crop 50x100% -shave 5x5 \) -geometry +5+5 -layers composite result.png
To check, I flatten over a blue background:
convert result-0.png result-1.png -background blue -flatten result.png

Export Multiple PSD Layer file to PNG while applying tint effect to each layer

We have the following PSD
https://app.box.com/s/rf514j3wnic1xkt6y1q3b5qnk0zds2rl
This is a transparent PSD with one base layer for the ring metal.
And additional layer for each individual stones.
Something like https://app.box.com/s/i8lhshbl27pvjmmczjq2bhla4mzw9cwn
and this
We want to be able to apply tint to each individual stone layer based of user input and export the final image as PNG file. To provide users the ability to design the ring to their liking.
Now I am trying to figure out what is the best way to achieve this functionality ?
We would like the image generated server side in .net so it can be shared.
What is the best way to approach this. I am thinking of using an image library like imagemagick to convert the image.
But I am unable to locate any examples where you can alter multiple layer with in a PSD file before converting it to another file format.
Any example or suggestion on methods to achieve this will of great help.
Editing layered PSD files is not going to be easy. I would suggest you maybe save the ring and each of the gemstone layers as a separate PNG file. Then you can do something along these lines with ImageMagick:
#!/bin/bash
convert ring.png \
\( layer-1.png \( +clone +level-colors red \) -compose Multiply -composite \) -compose overlay -composite \
\( layer-2.png \( +clone +level-colors green \) -compose VividLight -composite \) -compose overlay -composite \
\( layer-3.png \( +clone +level-colors blue \) -compose LinearBurn -composite \) -compose overlay -composite \
\( layer-4.png \( +clone +level-colors "#ffff00" \) -compose Saturate -composite \) -compose overlay -composite \
result.png
Giving you a PNG file like this:
You may like to experiment with the blending modes, I just tried a few that looked vaguely pleasing to my eye. If you want a list of all available blending modes, you can do:
identify -list compose
Atop
Blend
Blur
Bumpmap
ChangeMask
Clear
ColorBurn
ColorDodge
Colorize
CopyBlack
CopyBlue
CopyCyan
CopyGreen
Copy
CopyMagenta
CopyOpacity
CopyRed
CopyYellow
Darken
DarkenIntensity
DivideDst
DivideSrc
Dst
Difference
Displace
Dissolve
Distort
DstAtop
DstIn
DstOut
DstOver
Exclusion
HardLight
HardMix
Hue
In
Lighten
LightenIntensity
LinearBurn
LinearDodge
LinearLight
Luminize
Mathematics
MinusDst
MinusSrc
Modulate
ModulusAdd
ModulusSubtract
Multiply
None
Out
Overlay
Over
PegtopLight
PinLight
Plus
Replace
Saturate
Screen
SoftLight
Src
SrcAtop
SrcIn
SrcOut
SrcOver
VividLight
Xor
I also specified some colours by name and one by hex, so you can see how to do it that way if you prefer.
P.S. If you keep all your artwork as PSD files, you can always use Adobe's ExtendScript to script the export of the various layers as separate PNG files with a single keypress...
P.P.S. It is possible for ImageMagick to extract the layers from a PSD file itself, but I extracted the layers from your file and they are not all the same size as the background image and I cannot find their correct positioning relative to it. If you know something about how the layers were created and whether they could be made identical size and aligned with the background, you could replace layer-n.png in my examples with PhotoshopFile.psd[n]
P.P.P.S. If you want to do this server side in .NET you should take a look at the .NET library for ImageMagick that can be found here: https://magick.codeplex.com/. If you need help translating the commands above to C# you could ask a question on the discussions page there.

Compositing premultiplied images using ImageMagick

I have two images. One is background with no alpha. The other is a white cloud. The alpha of the cloud image is premultiplied with black. When I composite them the white cloud has black in it, so it looks grey instead of white like it should. I'm doing:
convert -gravity Center bg.tga whitecloud.tga -composite comp.tga
Is there a way to composite premultiplied images in ImageMagick, or does the image have to be non-premultiplied? Can I make a premultiplied image non-premultiplied using ImageMagick?
Update:
Ok, here are the images as TGA for download:
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/bg.tga
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/whitecloud.tga
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/aftereffects.tga
http://acatysmoof.com/posting/problems/imagemagick/premultiplication/imagemagick.tga
and in the same order as jpgs to view in your browser:
I tried all the modes provided, but none of them create the same result as After Effects.
It would be easier if you showed your images, but try adding -compose lighten before -composite in your command, like this:
convert a.tga b.tga -compose lighten -composite out.tga
Basically that will make ImageMagick choose the lighter pixel of the two images at every point.
If that doesn't work, try other blending modes
for b in $(identify -list compose); do
convert -label "$b" bg.tga whitecloud.tga -compose $b -composite miff:-
done | montage - -tile 5x out.png
I am kind of thinking Atop, Dissolve, SrcAtop and SrcOver might be your friends but have a look full-size and see what floats your boat. That would be
convert a.tga b.tga -compose Atop -composite out.tga
Here is an Imagemagick command that does what you want:
convert -gravity Center whitecloud.tga -fx "u/max(u.a, 1/255)" bg.tga +swap -composite -fx "u*u.a" comp.tga
What's happening here?
-fx command #1: Convert whitecloud.tga from premultiplied alpha to "normal". The max() operator is a special case to avoid dividing by zero.
+swap command: Make bg.tga the first image and the revised whitecloud.tga the second.
-composite these two regular, non-premultiplied images.
-fx command #2: take the result, and return to a premultiplied alpha format.
This gives exactly the same result as After Effects.
Note that, as I wrote it, it only works for an opaque bg.tga. You'd need to do some extra work to handle a transparent background image.
If you want to duplicate the After Effects result, then I believe what you want to do in ImageMagick is the following -- composite the background image with a white image using the cloud as a mask:
convert bg.tga \( -clone 0 -fill white -colorize 100 \) whitecloud.tga -compose over -composite cloud_blue.tga
I have posted a JPG result, but my .tga result is the same.

Masking an image's alpha in Imagemagick

I need to create an image to be used as a rollover background image. It's a circular pattern that is split into 8 pieces. Here's a screengrab of the main image (png with transparency):
And here's a screengrab of the mask image. It's the same size as the main image and features 'pie' pieces in order to mask all but the sector that is being hovered over.
I'm including screengrabs, as I believe the answer should be pretty simple (aren't all answers simple when you know them?!) so I'll save bandwidth, but I can upload the original files if it's helpful.
Here's the command I'm using to create the new masked image:
convert main.png \( mask.png -colorspace gray -alpha off \) \
-compose copy-opacity -composite new.png
The trouble is that the new image created has flattened the original image's alpha to a black background:
How do I get Imagemagick to preserve the original png's transparency?
You want masked composition to do this. http://imagemagick.org/Usage/compose/#mask
The technique is to compose the original image (the src) onto a fully transparent image of the same size (the dst), using a mask to limit composition area (the mask). It is a special case of the -composite operator, and involves 3 images, rather than 2 like the rest of the compose methods. You don't specify any -compose mode for this.
A quick way to get the fully transparent dst that you need for this technique is to clone the src image and zero out its alpha channel, then swap the order of src and dst so that they are in the right order for the -composite operation to follow:
convert main.png -alpha on \( +clone -channel a -fx 0 \) +swap mask.png -composite out.png
I was not satisfied with retroj's solution as it seems to ignore the grayscale of the mask.
This one worked for me:
composite -compose Dst_In \( mask.png -alpha copy \) main.png -alpha Set PNG32:result.png
or
convert -compose Dst_In \( mask.png -alpha copy \) main.png -alpha Set -composite PNG32:result.png
Dst_In method multiplies the alpha channels of two images. The trick here is to convert the grayscale mask to an alpha channel for it which is done with -alpha copy.

Resources