I'm working on a photo application and I need some advice how should I solve the following with Graphics/ImageMagick.
Given a photo with resolution: 2048x1536
Given a specified resolution: 1864x1228
Resize the image and fill the specified resolution with the image (now it's 1864x1398)
Highlight the area of the original image will be cropped (to 1864x1228)
I have a working solution which resizes and crops the image properly:
IMOperation resizeOp = new IMOperation();
resizeOp.addImage();
resizeOp.resize(MAX_WIDTH, MAX_HEIGHT, "^");
resizeOp.gravity("center"); //centered image with crop the top/bottom parts
resizeOp.crop(MAX_WIDTH, MAX_HEIGHT, 0, 0);
resizeOp.addImage();
ConvertCmd cmd = new ConvertCmd(true);
cmd.run(resizeOp, fileName, outputFileName); //cropped, center filled image (1864x1228)
The question is how should I do the following: show the full image instead of the cropped version and highlight the area of the image will be cropped. I'd prefer with red border around the cropped image and show with the cropped parts with alpha layer.
I have an idea which I don't like very much: generate an image from the original with alpha layer and put the cropped image on it with red border. It doesn't seem to be the optimal solution :) My other idea is to do this with javafx imageviews, but it seems suboptimal as well.
Notes:
I'm using im4java with GM. I accept a command line solution too (and I'll figure out and post it in im4java ;)
We can restrict the conversation about horizontal images only, I can figure out the vertical operations
Any comments would be highly appreciated.
The oneliner imagemagick convert (remove the line breaks):
convert ( in.jpg -resize 1864x1228^ -fill white -colorize 50% )
( in.jpg -resize 1864x1228^ -gravity center -crop 1864x1228+0+0 )
-gravity center -composite out.jpg
In bash, you have to escape the () characters with \!
I solved it in im4java with sub operations:
IMOperation op = new IMOperation();
op.openOperation();
op.addImage(); //input image
op.resize(MAX_WIDTH, MAX_HEIGHT, "^");
op.fill("white");
op.colorize(50);
op.closeOperation();
op.openOperation();
op.addImage(); //input image
op.resize(MAX_WIDTH, MAX_HEIGHT, "^");
op.gravity(GRAVITY_OPT_CENTER); //centered image with crop the top/bottom parts
op.crop(MAX_WIDTH, MAX_HEIGHT, 0, 0);
op.closeOperation();
op.gravity(GRAVITY_OPT_CENTER);
op.composite();
op.addImage(); // output image
Notes:
It still doesn't contain red border (I can't add border only to the second image).
I decided to use "fade to white" effect, instead of playing with alpha channel.
Example:
input: http://i.stack.imgur.com/lhMgT.jpg
output: http://i.stack.imgur.com/EYO7c.jpg
Related
I would like to blur only a part of an image. The part to blur is always rectangular, so that I can easily use the following command:
magick source.jpg -region 1000x1000+0+500 -blur 0x20 result.jpg
This works, but is pretty slow for large images. Since I have to process thousands of files again and again, this will simply take too long.
Therefore, I decided to do the blurring by downscaling and upscaling the image back to the original size. However, since this will blur the full image, I have tried to accomplish the task using the following steps:
take the original image as background
create a copy of the original image
blur the copy using down-/upscaling
crop the desired region from the blurred copy
compose the original and the blurred&cropped copy
I am already pretty close (I hope), but when composing the two images, the cropped image will always be positioned in the top-left corner of the original image - instead of the original position from the source image. This is my current command:
magick source.jpg ( -clone 0 -resize 5% -resize 2000% -crop 1000x1000+0+1000 ) -composite result.jpg
I have read in the documentation that the original canvas size will be retained when using the -crop operation, and that this size and position will be used when using -composite. However, this doesn't seem to work in my case. Does anyone have an idea why?
I have tried to use -repage, -extent and other options to define the size and position of the cropped image, but to no avail so far.
I would try -flatten in your command as that is used for layers.
You can do it with a mask image (of any shape) in ImageMagick. Though I am not sure if that will be faster than your scaling method.
Input:
Mask:
(note: blurring occurs where mask is black)
magick lena.jpg -write-mask mask.png -blur 0x3 +write-mask lena_blurred.png
Result:
I am using ImageMagick to place an image on particular location on a white background canvas, can someone help me with it?
Here is what i tried so far, this would resize my image to correct resolution and put on a right size canvas.
Convert image.jpg -resize 1025x1537 -background white -extent 1920x1536
Now, I need to move it 40 pixles to the right , 20 to bottom
Reading the documentation for the geometry argument, it seems like one can use:
... -extent 1920x1536+40+20
If you want to define the offset from another origin, then you can use -gravity type.
https://imagemagick.org/script/command-line-processing.php#geometry
https://imagemagick.org/script/command-line-options.php#gravity
I have a JPG image with a known size of 3072x2048. Now I want to rotate that image by any degrees (e.g. 45), while keeping its original size. Thus - using ImageMagick on the command line - I first want to rotate, then crop the image, like this:
convert -rotate 45 -gravity center -crop 3072x2048 +repage original.jpg rotated-45.jpg
By using -gravity center I specify to crop the center part of the image, which is what I want. This operation produces four output images:
rotated-45-0.jpg
rotated-45-1.jpg
rotated-45-2.jpg
rotated-45-3.jpg
The first image rotated-45-0.jpg is exactly the final image I want to get. The other three I don't need. I could delete them, but I think it would be nicer to not generate these "extra" images in the first place. So I thought I could do it with this command instead:
convert -rotate 45 -gravity center -crop 3072x2048+0+0 +repage original.jpg rotated-45.jpg
This only produces one output image, however, now the top-left corner of the image is being cropped. So apparently the -gravity center is not used any longer.
Any ideas what I am missing here?
Using ImageMagick you can rotate an image any number of degrees while keeping the original canvas dimensions using "-distort SRT"...
convert original.jpg -virtual-pixel black -distort SRT 45 rotated-45.jpg
Use "-virtual-pixel" to specify how you want to handle the parts that were outside the canvas before the rotation. In this example I used "black". You can use black, white, background, tile, mirror, or none.
I know it is possible to trim all transparency around image to make image smaller and contain only the image. But is it also possible to somehow know the location of "box", that contains the image?
For example I have 100x100 transparent image, which contains something at 10x10 box having topleft corner at x=15,y=15. Rest is all transparent.
I'd like to end up with 10x10 image, all transparency around trimmed, but also having that 15,15 information. Those are probably 2 separate actions. How do I do this in a script?
Just fyi - I am having bunch of images like this and they are layers, that I need to trim and stack onto eachother to make them clickable.
There are lots and lots of words but no image in your question so I am trying to guess what you want. I made this input image:
magick -size 100x100 xc:black -fill white -draw "rectangle 10,20 50,80" image.png
And I think you want to know the trim box, which is where it would trim to if you ran -trim:
magick image.png -format "%#" info:
41x61+10+20
So that's a 41x61 box with the top-left at (10,20).
I have some images that have a transparent border of varying width; I'd like to crop these to the visible parts of image. (I imagine a solution won't be specific to the transparent part, but would work with a frame of any color.)
E.g. the 200x200 image below has a transparent border of 3 pixels. I'd like to get the equivalent of
$ gm convert a.png -crop 194x194+3+3 b.png
without having to determine the numbers by hand. Is this possible with graphicsmagick (or imagemagick)?