Wrapping an image over a product image convexly - imagemagick

What I want: When I apply an image over the pillow texture the artwork of the image should wrap convexly on the pillow.
Here is the link for the desired image
Above output is the correct output that I want
Note: In the above image, you can see the image is wrapped around the corners and convex from the center.
Problem: But when I apply image over the pillow texture image artwork is not curved convexly.
Here is the the output I currently have
Also, for reference,
here is the product image that I am using
And here is the artwork, that I am overlaying it with
Also, in the product image linked above, as you can see, there is some distortion in the top left corner, if I am overlaying it with any design, how can I achieve that distortion as well.
I am new to imagemagick, so are there any good resources to learn from and practice with?

Here is how to do that in ImageMagick.
Input:
First make a mask for the pillow. ImageMagick could not get a good mask, so I used http://remove.bg to make the background transparent and then extracted the alpha channel and got this:
I then measured the size and offset of the white part of the mask:
convert mask.png -format "%#" info:
642x646+78+77
Then I processed the images. I resized the text image, then applied pincushion distortion (opposite of barrel distortion) and inserted it into a white image the size of the pillow at the offset location from above. Then using the mask, I did a blend composite of the pillow and distorted image to make the result. See https://imagemagick.org/Usage/distorts/#barrel
convert pillow.jpg \
\( -size 800x800 xc:white \
\( pillow_overlay.jpg -resize 646x646 -distort barrel "0.0 0.0 -0.2 1.3" \) \
-geometry +78+77 -compose over -composite +geometry \) \
mask.png -define compose:args=60,40 -compose blend -composite \
pillow_new.jpg

Related

Imagemagick: Create 1 image out of 3 with luminance/overlay mask

I want to generate an image out of 3 images. One of these images is the background, one the shape mask and one the color of the shape.
Here are the images:
shape.png
(transparent background, white circle in the middle and black circle inside and gray circle inside the black one)
shapecolor.png
background.png
The background.png should be the overall background. On top of that is the shape and all white parts (and also the white in the gray parts) should be in the color of shapecolor.png
I used simple mono color images to make it easier but I use some textures in reality ^^
I have no idea how to solve this problem in Imagemagick, the tool is very powerful and the documentation is not so easy to understand. Tried to solve this for 3h, but did not get the result, which should look like this:
Can anyone help please?
Here is one way to do it in Imagemagick. In the second line, extract the alpha channel from omg.png and save it in an mpr: in-memory image and then delete the clone. Then I use the mpr: image later in the last step.
convert red.png img.png \
\( +clone -alpha extract -write mpr:alpha +delete \) \
-compose multiply -composite \
green.png +swap mpr:alpha -compose over -composite \
result.png

Image rotation relative to wrong (top right) point

I am trying to place a rotated image onto a blank canvas.
This is the command i am using:
convert "(" -size 1000x1000 xc:transparent ")" "(" "img.jpg" -virtual-pixel white -rotate -10.75 ")" -geometry +136+148 -composite "overlay.png" -geometry +0+0 -composite out.png
I would expect the image to appear at +136+148 rotated around its center. However, it appears to be rotated around its upper right corner instead.
I confirmed this in Photoshop:
This is the resulting image (using slightly different size but same parameters as my example command given here):
The 4 lines are the guides that mark the coordinates that define where the image sits. As you can see, the image is rotated -10.75 degrees. And the rotation center is the upper right corner.
Here i select the box at the correct coordinates in Photoshop:
And here i rotate it after setting the rotation point to the top right:
As you can see, the selection now matches the image as it was calculated by my convert command.
I have tried dealing with this for many hours. I tried switching to +distort and -distort and what not, but there i simply get either a cropped image or another wrongly positioned bounding box.
I don't know how to address this problem. What am i doing wrong? How can i tell -rotate to rotate my image around its center, not around the top right corner (why top right anyway?).
Thank you for your help!
The default gravity for offsetting is the northwest corner or top-left corner. The geometry offset you are using moves the top left corner of the padded rotated image after its background has been added and not the top left corner of the where the Input gets rotated. So I think that may be why you are not getting the expected result. ImageMagick -rotate does rotate about its center, but it fills the background out to make a complete rectangular image that is the bounding rectangle about the rotated image.
In ImageMagick, a better approach to what you did would be to use -gravity center and align the center of the rotated input image with the center of the transparent region in the overlay image.
Alternately, measure the 4 corners of your transparent region in the overlay and 4 corners of the input image and do a perspective or affine distortion to align the two.
Here is how to do it in bash unix syntax.
over1="122,186"
over2="466,118"
over3="510,345"
over4="166,411"
WxH=`convert -ping "Image.jpg" -format "%wx%h" info:`
ww=`echo "$WxH" | cut -dx -f1`
hh=`echo "$WxH" | cut -dx -f2`
ww=$((ww-1))
hh=$((hh-1))
in1="0,0"
in2="$ww,0"
in3="$ww,$hh"
in4="0,$hh"
convert overlay.png \
\( Image.jpg -virtual-pixel none +distort Perspective \
"$in1 $over1 $in2 $over2 $in3 $over3 $in4 $over4" \) \
-layers merge +repage \
out.png
See https://imagemagick.org/Usage/distorts/#perspective
Try using the offset geometry that aligns with the outer edges of your target area. That would be more along the red lines I've added here, not along the cyan lines in your example image.
Edited to add: For a method of finding the proper offset information to fill the hole and placing the image under the hole, see my other answer in this thread.
You can find the location of the cutout in your overlay image, then use that information to properly place your under image with a command like this...
convert overlay.png -background none \
\( +clone -alpha extract -trim \
-set option:offset +%[fx:page.x]+%[fx:page.y] +delete \) \
\( image.jpg -rotate -10.7 -set page %[offset] \) \
-set page %[fx:u.w]x%[fx:u.h] +swap -layers merge result.png
This makes use of the fact that the bounding box dimensions of the rotated input image are the same as the bounding box dimensions of the cutout of the transparent region in the overlay image.
That reads in the overlay, and inside parentheses it makes a clone of it, extracts the alpha channel, and trims the result to find the offset of the cutout. It saves the offset to a variable named "offset".
Then inside another set of parentheses it reads in the under image, rotates it the known -10.7 degrees, and uses that variable "offset" to set the paging offset on the rotated "image.jpg".
Then outside the parentheses it uses the width and height of the overlay to set the paging dimensions for the under image.
It finishes by swapping the order of the images to put the overlay on top, then merging the two layers to create the output.
Here is an alternate to GeeMack's excellent ImageMagick solution. This computes the center of the original input.jpg, and the center of the transparent region in the Overlay.png. Then it uses +distort SRT to translate and rotate the image before finally compositing with -layers merge.
convert Overlay.png \
\( +clone -alpha extract -trim -set option:center "%[fx:page.x+w/2],%[fx:page.y+h/2]" +delete \) \
\( Image.jpg -virtual-pixel none +distort SRT "%[fx:w/2],%[fx:h/2] 1 -10.7 %[center]" \) \
+swap -layers merge +repage result2.png
The second line is much line GeeMack's, but it computes the center of the transparent region's bounding box and saves that in the "center" argument and then deletes the trimmed image.
The third line computes the center of the Input.jpg image (before rotation). It then uses +distort SRT to translate from the input center, (scale=1) and rotate -10.7 and translate to the center of the transparent region's bounding box.
See https://imagemagick.org/Usage/distorts/#srt

Imagemagick crop transparent image to mask

So here is my original image (note the transparent border) src.png:
Here's the mask I want to use to crop. White means keep, black means crop mask.png: (Note that it isn't necessarily going to be a square. It could be a heart or a star or anything)
I also have transparent.png, which is a fully transparent image. All three images have the same dimensions.
So, running this command generates the following image:
convert transparent.png src.png mask.png -composite out.png
Which is masking perfectly, but now I want it cropped to the size of the white mask area. Using -trim is sort of close, but it gets rid of the transparent areas that are inside the mask.
How can I resize the masked image to the size of the white area in the mask?
I am not sure I understand what you want for the result. Why do you need the fully transparent image? Do either of these do what you want?
Full sized transparent image with masked area showing:
convert src.png mask.png -alpha off -compose copy_opacity -composite result1.png
Trimmed to just the part you want:
convert src.png mask.png -alpha off -compose copy_opacity -composite -trim +repage result2.png
Not sure I understand what you are trying to do, not least why you need a full size transparent canvas. Your command does not give the same results on my ImageMagick version 7.
This command may be what you are looking for:
convert src.png mask.png -compose darken -composite -trim out.png
It gives this - I have artificially added a red border so you can see the full extent on StackOverflow's white background:
Or maybe you want the trim box from your mask and to use that to crop your source:
convert mask.png -format %# info:
113x113+570+33
convert src.png -crop 113x113+570+33 result.png
If you want to crop a square from picture, you no needs using mask, just crop it:
magick Uq328.png -crop -crop 111x111+570+331 +repage cropped.png
according to https://legacy.imagemagick.org/Usage/crop/

Apply gradient mask on image that already has transparency with ImageMagick?

I've got a PNG image with transparency:
original.png
Now I want to use ImageMagick to apply a diagonal gradient to its alpha channel. I mean so that its opacity remains in the top left corner, and gradually fades out to completely transparent in the bottom right corner. Like this:
result.png
So basically I want to generate a gradient, and use that as a mask for the image. But the image already has an alpha channel (transparency) of its own. Here's a visualisation of what I'm trying:
(original and result here displayed on checkerboard for visiblity, but I mean actual transparency)
I think I understand how to generate a diagonal gradient (the barycentric gradient command is very useful for this). But this creates a gradient in the color channels i.e. a colored or grayscale gradient. Whereas I want to apply the gradient on the alpha channel.
From the IM manual I understand the -compose CopyOpacity operator could be used for this. However this seems to copy the alpha from the mask on to my image. I need to "apply" this gradient color on my existing alpha channel, so basically I need my image's alpha channel to be multiplied by the grayscale color from the gradient image.
What would be the correct IM command line to perform the operation displayed above?
Here is one way you could do it:
convert tree.png -write MPR:orig -alpha extract \
\( +clone -colorspace gray -fx "1-j/h" \) \
-compose multiply -composite -write alpha.png \
MPR:orig +swap -compose copyopacity -composite result.png
The -write alpha.png can be omitted - it just shows the alpha layer for debugging and illustration purposes.
The MPR is just a temporary copy of the original image that I hold in memory while I am dinking around with the alpha channel and which I bring back near the end. The gradient in the alpha channel is generated by the -fx and I made the colorspace gray first so it only has to run once, instead of three times.
If you knew the dimensions of the tree image up front, you could replace the part in parentheses with:
-size WxH gradient:black-white
but I don't know the dimensions up front and I don't want a second convert command to get them, so I basically clone the original image's alpha channel to get a canvas the right size and fill it in with -fx.

Imagemagick: distorting images on top of background?

I've got one background image: sky.jpg
And two transparent PNG images: gradient.png and tree.png
Now I want to draw the two images on the background with a perspective distortion, like this:
The destination coordinates of the two images are, in clockwise order (starting top left) :
gradient: 62,129 421,218 383,458 147,548
tree: 445,100 765,47 698,368 529,396
I cannot figure out how to start with one image (in this case the sky background) and then take another image and draw that with perspective distortion to specific destination coords within the background. Also doing this with more than one image at a time, within one convert command, troubles me.
For example, when I start with just one image (the gradient) and try this:
convert sky.jpg \( gradient.png -alpha set -virtual-pixel transparent \
+distort Perspective "0,0 62,129 255,0 421,218 255,255 383,458 0,255 147,548" \) \
-compose src-over -composite result.jpg
It gets correctly warped (so the coordinates are relatively correct) but it's drawn in the top left corner, not at the coordinates I specify.
Also I'm a bit unsure if my usage of -compose and -composite is correct (I took this from various IM manual examples).
One other thing that is unclear to me: in case of the 256x256 image, should I use 255,0 and 255,255 and 0,255 as the corner coordinates, or 256,0 and 256,256 and 0,256 ?
Any IM experts who can shed light on these issues?
Add a -geometry just before the -composite like this:
convert -size 800x600 xc:black \( -size 300x200 xc:red \) -geometry +90+10 -composite result.png

Resources