What is the most efficient, idiomatic way with ImageMagick to turn this:
Into this:
Please note: canvas size remains unchanged, a frame of arbitrary color and width is applied "on top" of the original image.
I think I would just shave 30 pixels off then add 30 pixels of border back on:
convert rose.jpg -shave 30 -bordercolor cyan -border 30 result.png
I'll let you do the colour-matching ;-)
Related
With a few thousand images like the following one, with complex edges from scanning (first a perfectly regular white one, then a very fuzzy gray/black'ish one), is there a good algorithm to figure out the coordinates of the area-to-keep? In the below example, going clockwise from the north-western corner, the optimal coordinates would be:
121,18
1934,18
1934,1312
121,1312
So that from this input image...
... can be cropped to remove anything tinted red, as shown here:
To clarify, I do know how to use ImageMagick or other tools to crop to that area. What I'm not sure about is how to figure out how to get to those above numbers? Do you just binarize the image and then go left to right until you hit "white" for the first time, then do the same from top to bottom, right to left and bottom to top? Or is there some library, script, etc. which already does that for you?
I would use vertical and horizontal projections of the image. By a simple detection of the highest transition, you easily find the limit between the background and the paper.
Your image has a border of white surrounding a border of black. So you can do two fuzzy -trim processes after padding with the appropriate color to ensure it goes all around the image. So in ImageMagick 6, it would be
Input:
convert book.jpg -bordercolor white -border 1 -fuzz 55% -trim +repage -bordercolor black -border 1 -trim +repage book_trimmed.jpg
Result:
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)?
I tried to add a border to an image of dimension 200x200 px using the below code.
convert -border 2x2 -bordercolor "#cccccc" old.png new.png
The above code ads a 2 px border around the old.png. Therefore, the image expands to 204x204 px.
However, I want to add an inline border. I have no issues with border overlaying edge portions of the old image. Thus, the new image should be able to retain the dimensions 200x200 px. Please advise how exactly to do that.
You need to shave two pixels all around and then add a two pixel border. You should try this with Imagemagick 6. If using Imagemagick 7, replace convert with magick.
convert old.png -shave 2x2 -bordercolor "#cccccc" -border 2 new.png
I want to put some white space around an image in equal length. I want to maintain the image pixel ratio to 12:7 too. Any help would do a great help. Thank you.
Another method using Imagemagick V7:
magick ShF4m.jpg -background white -gravity center -extent "%[fx:w+20]"x"%[fx:h+20]" result.jpg
Open image, set the background to white, set the gravity to the centre so the -extent extends the canvas in all directions, increase the canvas size by 20px on the width and 20px on the height.
It would be simple in ImageMagick if you wrote over the inside of the border with white. That way you do not change the image dimensions nor aspect ratio. Here I shave 10 pixels all around and then put a 10 pixel white border all around. Here I will add a red border just to make it visible. But you can change red to white later.
convert barn.jpg -shave 10x10 -bordercolor red -border 10x10 barn_border10.jpg
It would be very hard to add white outside the image of equal amount and keep the aspect ratio. I do not think you can have equal white border amounts and keep the aspect ratio.
I have an overlay image, which is like a watermark/logo, which needs to be overlayed on top of the source image (while preserving alpha channel, etc)
When overlay is the same or smaller dimension as the source image - things are easy:
composite.exe -alpha on -gravity center logo.png in_image.jpg out_image.jpg
However, when logo.png is larger than in_image.jpg - above call truncates the logo, and out_image.jpg has the same dimensions as in_image.jpg
I would like the resulting image to be the largest of either the logo.png or in_image.jpg so I can do things like artistic frames around the photos.
Below image demonstrates the end result I want to be able to get this:
Desired Result
Note, here, the png with skulls has larger dims than the kiddo's image. The alpha channel needs to be preserved.
Edit: more clarity through examples
Here is another desired result
Here, the png file is opaque on the sides, has a clear window in the middle, and half-translucent bubbles. the JPG file is just a regular JPG from a camera.
Would love to add original and logo files that result in it, but lack reputation to add more than 2 links (or to add images)
Updated Answer
If you have v7 of ImageMagick, you can get it to do the maths for you all in one line using -fx to determine the dimensions of the larger of the two images:
magick background.jpg overlay.png -background none -gravity center -extent '%[fx:u.w>v.w?u.w:v.w]x%[fx:u.h>v.h?u.h:v.h]' -composite result.png
That basically says... "Extend the two images as follows. If the width of the first image (u.w) is greater than that of the second image (v.w), then use the width of the first, else use that of the second. Same for height.".
Original Answer
I believe you want this. Get width of whatever is wider of background and overlay. Get height of whatever is taller of background and overlay. Extend both background and overlay with transparent pixels to new dimensions. Overlay.
So, if we start with this as background (300x50):
And this as overlay (122x242) - which is a tall blue rectangle surrounded with transparency then that is bordered in black to show the extent of it:
You would run this, which is actually very simple but it is full of comments and debug output so you can see what is going on:
#!/bin/bash
# Get background width and height
read wb hb < <(convert background.jpg -format "%w %h" info: )
echo "Background: " $wb $hb
# Get overlay width and height
read wo ho < <(convert overlay.png -format "%w %h" info: )
echo "Overlay: " $wo $ho
# Get wider of the two
w=$wb
[ $wo -gt $w ] && w=$wo
# Get taller of the two
h=$hb
[ $ho -gt $h ] && h=$ho
echo "New dimensions: " $w $h
convert background.jpg overlay.png -background none -gravity center -extent ${w}x${h} -composite result.png
Here is how it looks running:
Background: 300 50
Overlay: 122 242
New dimensions: 300 242
Presumably, when you have done your overlay, you would add -trim as the final part of the command line to remove any extraneous stuff that has been added.
Try using convert rather than composite. It is more flexible than composite.
convert logo.png in_image.jpg -gravity center -compose over -composite out_image.jpg
But if you insist on using composite, then
composite in_image.jpg logo.png -gravity center -compose src_over out_image.jpg
Note sure exactly what you mean by preserving the alpha channel, since jpg does not support transparency. Perhaps you can post a pair of inputs and your desired output, if what I have posted does not do what you want.