we run a mogrify batch job like mogrify -path "WEBREADY\DONE" -layers merge -trim +repage -resize "1200x1200>" -define jpeg:extent=500kb -format jpg *.*
This works fine for images with a white background. But recently we saw a 2% error rate and discovered the error. Mogrify trims as expected only on the web the images is surrounded by white so this looks quite silly with grey-ish in corners.
THe solution would be to either
Detect the non-white background. And in that case -only- do not trim
Or to detect the background color (it is JPG) in top left corner and forst set this to an all white background.
Can this be done in my 1 command above for the commandline? (so find the grey background first and change it to white)
You can get the colour of the top-left pixel like this:
convert shirt.jpg -crop 1x1+0+0 txt:
# ImageMagick pixel enumeration: 1,1,65535,srgb
0,0: (57311,57311,57311) #DFDFDF srgb(223,223,223)
So, it is #DFDFDF.
If you now try and replace that shade with yellow (I know you want white but you can't see that on here):
convert shirt.jpg -fill yellow -opaque "#DFDFDF" result.png
and you can now see the problem. The background is not uniform and its colour also appears in your shirt. If you add some fuzz, it makes it more pronounced:
convert shirt.jpg -fill yellow -fuzz 10% -opaque "#DFDFDF" result.png
Even if you try flood filling from the top-left, you still have to hope that there are no pixels in the edges of your shirt that are similar to that corner:
convert shirt.jpg -fill yellow -fuzz 5% -floodfill +0+0 "#dfdfdf" result.png
Related
I've image an image with white background. I used command to make it transparent convert imoji.png -fuzz 20% -transparent white result.png I got the result.png. The command has removed pixels inside the emoji and some other parts. I need it to be something like this. I made it using photoshop by reducing the tolerance of the magic wand tool. Help me to do the same using the convert command in the terminal. I reduced the -fuzz 20 to 1% still not getting the result.
Use flood fill from the top left corner of the image in ImageMagick.
convert imoji.png -fuzz 20% -fill none -draw "matte 0,0 floodfill" result.png
I have a series of images in PNG format that make up an animation.
I want to automate the process of cropping the excess transparency in the animation as a whole, so I need to find the unique smallest rectangular area such that, if every image were cropped to it, no opaque pixels would be trimmed from any image; then crop every image to this area.
IOW, the equivalent of making each PNG a layer in GIMP, doing "autocrop layer" on every layer, then "canvas size to layers", and reexporting every layer as a PNG again.
Is there a way to get mogrify or convert (or GIMP, for that matter, but I imagine in my case the number of images involved would take up too much memory to have them all as GIMP layers) to do this automatically?
If not, is there a scripting function that would return the autocrop rectangle for a given image, so I could check overlaps and find the smallest that would cover all of them, myself?
You can get the cropping box for an image like this:
convert input.png -format "%#" info:
245x114+4+2
So, in this instance it is 245px wide by 114px tall and offset [4,2] from the top-left corner.
So, to test the theory, let's make 3 images with transparent background and little red boxes to represent your content. I have added a black border just so you can see the extent on Stack Overflow's white background:
convert -size 200x100 xc:none -fill red -draw "rectangle 10,10 20,20" 1.png
convert -size 200x100 xc:none -fill red -draw "rectangle 180,20 190,30" 2.png
convert -size 200x100 xc:none -fill red -draw "rectangle 150,80 160,90" 3.png
So, I can get the cropping box for all 3 images combined like this:
convert [123].png -evaluate-sequence mean -format %# info:
181x81+10+10
And if I draw that on in blue:
convert result.png -stroke blue -fill none -draw "rectangle 10,10 191,91" -bordercolor black -border 1 result.png
I need to take a normal image:
and add a white, transparent overlay so it looks something like this:
Don't pay attention to the text on the converted image or the fact that it's a cropped version of the original. I need to simply convert the top to the exact same image, just with this white, transparent overlay. I also need it to be a cli command.
Updated Answer
This is even easier
convert house.jpg -fill white -colorize 80% result.png
Original Answer
Something like this maybe...
convert house.jpg \( +clone -fill white -colorize 80% \) -composite result.png
I've lots of images with a white background and I need to remove it (make it transparent). I've already tried imagemagick convert and for some image that worked quite well, but still cannot be used on dark background.
I'm kind a noob in this branch of programming... Someone know some good algorithms to remove the background?
Plus, would be great if it could correctly process an image like this:
http://dev.addvert.it/cache/24eeab00e5987452d09fbeec0c7678d6_w472_h472_sc.jpg
The problem with convert diff is it erase a lot of the image, while the border algo doesn't touch the central part.
I totally understand how hard is for a calculator to do something like this and I'm pretty amazed with the results of convert, but if there's the chance of a better solution, why not ask? :D
You are not constrained to converting white pixels to transparent. You could maybe take the colour of the top-left corner pixel and make all pixels that colour transparent and it will work for black backgrounds too:
As suggested by #emcconville, the first of the following two options is more succinct:
convert towel.jpg -fill none -fuzz 2% -draw 'matte 0,0 replace' output.png
or, per my original,
convert towel.jpg -alpha on -fill none -fuzz 5% -draw 'color 0,0 replace' output.png
You may find this more readable...
convert towel.jpg -fuzz 5% \
-transparent $(convert towel.jpg -format "%[pixel:p{0,0}]" info:) \
output.png
In the second line, $(convert ...) just gets the colour of the top-left pixel and feeds that into the middle of the outer convert command as the colour to make transparent - but it is only doing the same thing as the first version.
I've a number of images with transparent pixels both inside the graphics and outside. One example is:
and
So now I want to fill only the internal transparent pixels (the ones within the black boarder), is there any batch processing way to do it? I tried imagemagick convert tool, but didn't figure out how to the the "selective" conversion.
Thanks for any help!
there are following ways how can accomplish that (it all depends on how the image is composed):
if you know the part you want to keep transparents starts at 0x0
You start by removing all transparency with something like http://www.imagemagick.org/Usage/masking/#remove
and then re-add the transparency using flood-fill starting at 0x0 http://www.imagemagick.org/Usage/masking/#bg_remove
You have more control over whats going on by using a transparency mask:
then you start modifying the mask (which is now only black/white), by coloringusing floddfill starting wiht 0x0 (i.e. with blue), replacing the black with white and then replacing all blue pixel with black (for color replacement see http://www.imagemagick.org/Usage/color_basics/#replace)
# the mask
convert original.png -alpha extract mask.png
convert mask.png -fill blue -draw 'color 0,0 floodfill' mask_blue.png
convert mask_blue.png -fill white -opaque black mask_filled_blue.png
convert mask_filled_blue.png -fill black -opaque blue mask_filled.png
# change transparent to skyblue
convert original.png -background skyblue -alpha remove -alpha off original_nontransparent.png
# apply the modified mask
convert original_nontransparent.png mask_filled.png -alpha Off -compose CopyOpacity -composite final.png
Note that this techniqe works only moderatly well with half transparent things (see http://www.imagemagick.org/Usage/antialiasing/#floodfill ).
For better results with half-transparency you might want to use different methods to "fill" the mask. You would i.e. just draw a shape instead of the two fill operations on the mask:
convert mask.png -fill black -draw "circle 40,80 60,60" mask_filled.png
this will fill the center, but keep the half transparency intact.
if you know the "center" is always trnsparent, you could also floodfill from the center.
Hope this helps