How to replace white background color with transparent of an image in ImageMagick? - imagemagick

I have an image in .jpg format with white background color. I want to remove the white background color to transparent in Imagemagick. I tried many ways but still the white background can not be removed. Can some one help me to solve this.

You cannot have transparent background colors in your JPEGs. The JPEG file format doesn't support transparency.
If you need transparent background, you need to convert the JPEG to
either PNG (high quality, filesize possibly larger than JPEG)
or GIF (in case you can tolerate low quality and a range of maximally 255 colors).
Example command:
convert your.jpg -transparent white your.png

First, you need to convert the image format from .jpg to .png format, because JPEG does not support transparency. Then use this command:
convert image1.png -fuzz 20% -transparent white result.png
The -fuzz option allows the specified percentage deviation from the pure white colour to be converted to transparent as well. This is useful, for example, when your image contains noise or subtle gradients.

I just found a very neat thing!
magicwand 1,1 -t 20 -f image -r outside -m overlay -o 0 image.jpg imgOutput.png
It is a Fred Weinhaus bash script that can be downloaded from here (for non commercial use only). Also there has about 250 scripts!! and this one is amazing! it did exactly the trick, to remove all background while keeping the inner image dots untouched!
At his page, there are several images as examples so you pick what you need to put on the command line!
The initial position 1,1 is a general guesser saying all the contour is background.
Pay attention that the output must be ".png"

This is my solution without magicwand (replace magick by convert for im < 7.0):
magick img.png -fuzz 20% -fill none -draw "alpha 1x1 floodfill" result.png

Get the background automatically and remove it :
bg=$(convert input.png -format "%[pixel:p{0,0}]" info:)
convert input.png -fuzz 20% -transparent "$bg" output.png

Related

How can I specify a background in Imagemagick mogrify based on the colour of an existing pixel?

I want to use mogrify to set the background colour of a large number of images to be whatever colour is at a specific pixel, to make them square.
The vast majority have a single colour in the image background, or are photos in front of a single colour (so with only slight variations from shadows, etc.).
(The specific purpose in this case is to make the images all the same size and square for StyleGAN2-ADA training, so I want to avoid big "letterbox" rectangles where possible as it would be seen by the discriminator as relevant to the image, where a more faded-in background that approximately matches would be more likely to be ignored. Specifically, I have thousands of pictures of single dolls and action figures from various sources, some of which are "trimmed out" to have a truly solid colour background, others of which are against solid colour tables/walls/etc, for instance, from eBay images and such.)
Since they do not all have the same colour in the image background (the colour in the image, as opposed to the 'background colour' setting as per ImageMagick's jargon), I need to sample a pixel and set the background, but I can't figure out how. I tried things based on methods used to set the whole image to one colour, to no avail.
I have tried:
mogrify -verbose -resize 1024x1024 -gravity center -background 'p{10,10}' -extent 1024x1024 -resize 256x256 *.jpg
and
mogrify -verbose -resize 1024x1024 -gravity center -background "%[pixel:p{10,10}]" -extent 1024x1024 -resize 256x256 *.jpg
and neither works. I can't find any other possibilities in the documentation.
EDITED TO ADD: While testing various commands I came across a way to modify your original command to make it work on ImageMagick versions as far back as IMv6.8.
mogrify -resize 1024x1024 -set background "%[pixel:p{10,10}]" \
-gravity center -extent 1024x1024 -resize 256x256 *.jpg
The significant difference is setting the background color in an unusual way. Instead of the normal option -background <color>, this command uses -set background <color>. Then it behaves as expected using that +10+10 color as the background in the "mogrify" command.
For ImageMagick v7 use magick mogrify instead of just mogrify.
The following was my original answer. The suggestion for IMv6 "convert" may be quite useful for some workflows, but the answer above seems to be the simplest, most direct route.
PREVIOUS ANSWER:
ImageMagick v6 won't do that inline parsing of the color, but there are ways to get the same result, usually with IM's "convert" in a "for" loop in your shell. I don't know which shell you're using so I don't know how you'd write a "for" loop, but running this command inside the loop on each image should give you the results you described...
convert $image -resize 1024x1024 ( +clone -crop 1x1+10+10 ) +swap \
-resize 1024x1024 -gravity center -composite -resize 256x256 $image
That reads in the image, resizes it, makes a clone inside the parentheses, and extracts that pixel at +10+10. After the parentheses that single pixel get resized to a 1024x1024 square. Then setting the gravity to "center" and compositing the input image over that colored square gives you the result you described.

Preserving PNG transparency during a simple transformation in imagemagick

Task: i have an input png file (many actually, but i'll just loop the solution). It is 16x16 PNG, 32bit with partial transparency along edges.
It so happens that toolbar of a certain stupid platform requires 17x17 files. My problem is that imagemagick kills transparency when doing simple transformations.
So:
Sanity check:
convert add.png PNG32:add_COPIED.png
creates another 16x16#32bpp file. So far so good.
Transformation (gravity is fine):
convert add.png -extent 17x17 PNG32:add_17.png
creates a file with solid white background. That's not good.
What doesn't work:
I tried a serious number of combinations of transparent, transparent-color, background, alpha and flatten. Got nowhere.
What does work:
convert address_book.png -alpha Extract address_book_MASK.png
convert address_book.png -extent 17x17 PNG32:address_book_17.png
convert address_book_MASK.png -background black -extent 17x17 address_book_MASK17.png
composite -compose CopyOpacity address_book_MASK17.png address_book_17.png PNG32:address_book_FIN.png
While i have a working set of commands and I can get through the day, I honestly believe that this is the wrong way to do things - four commands that create 3 intermediate files that i need to delete later. Surely it can be done in a better way?
Set the background colour before changing the extent:
convert input.png -background none -extent WxH result.png

How to remove specific white space from image using ImageMagick

Currently, I have thousands of pictures where I want to get rid of white space around the object, but not inside the object. However, the white space is not constant. See pictures below.
Picture 1 :
Picture 2 :
Picture 3 :
Options like this don't work as they delete all white space in the images
convert image.png -fuzz 10% -transparent white output.png
Any suggestions?
What do you mean by getting rid of the white space? If you mean make it transparent, then in ImageMagick 6, you can do a whole folder of images using the mogrify command as follows:
The process involves padding the image with 1 pixel border of white to ensure white is all around. Then doing a fuzzy flood fill. Then remove the extra one pixel all around. I have assumed that the background color is nearly white. Change the fuzz value as desired.
Create a new directory to hold the output (or backup your input directory)
Change directory to the one holding your input images
mogrify -path path_to/outdirectory -format png -bordercolor white -border 1 -fuzz 20% -fill none -draw "matte 0,0 floodfill" -shave 1x1 *.png
Here are the resulting images.
Of course you will have to download them to see that they are transparent.
Note that the images that I downloaded were JPG. So if your images are jpg and not png as in your command, then change *.png to *.jpg. Or just use * to change all formats.
See
https://imagemagick.org/Usage/basics/#mogrify
https://imagemagick.org/Usage/draw/#matte
If using ImageMagick 7, change matte to alpha and change mogrify to magick mogrify.

ImageMagick remove background noise and leave it white

In order to be better prepared for the OCR process, I want to remove the background noise on my images.
Right now I play with -lat parameter of ImageMagick tool:
magick.exe image_02_RESIZED.jpg -lat 20x20+10% test.jpg
but it completely removes the background from the image.
This is the sample output of the mentioned command:
Instead of this - I need to have the white background with a black text on it. How to do this with ImageMagick for Windows?
Try specifying the color you want to replace with -opaque and the new color with -fill.
magick image_02_RESIZED.jpg -fill white -opaque black test.jpg
Here is the result of this command:
You can also add a tolerance with -fuzz to remove noise around text; here is a sample command with tolerance set to 5%
magick image_02_RESIZED.jpg -fuzz 5% -fill white -opaque black test_05.jpg
This is the result of the command with -fuzz 5%:
You can experiment a bit to find the optimal value for -fuzz

imagemagick mean image sequence and ignore alpha channel

I want to get the mean of a sequence of images by using Imagemagick. Therefore I use the following command:
convert *.png -evaluate-sequence mean MEAN.png
Each of my images does contain an alpha channel. What I want is: Combine all the images by ignoring the alpha channel.
When I combine the images, the alpha channel is considered in the "mean" method and my final image has transparency. That isn't what I want.
Result:
I tried to add the parameter -alpha off, but then Imagemagick converts the alpha channel to black.
convert *.png -alpha off -evaluate-sequence mean MEAN.png
Result:
Photoshop does it right. I load all images in a stack and create a smart object. When I use the "mean" method in Photoshop, the alpha channel is not considdered in the final result.
Result that I want with Imagemagick:
Does someone have an idea how to do that with Imagemagick?
What you need to do is to use the alpha channels as weighting images for each image. The total fraction of white values at each pixel from all the alpha channels would be the weight to use for the average. So something like this should do what you want or at least be close.
First, cd to your directory of images. Then run the following.
convert *.png -evaluate-sequence mean \
\( -clone 0 -alpha off \) \
\( -clone 0 -alpha extract \) \
-delete 0 +swap -compose divide -composite result.png
This will work if there is some image texture at each pixel coming from al least one image. That is at a given pixel all images are not totally black (transparent).
compare -metric rmse result.png mean_photoshop.png null:
125.167 (0.00190993)
So this shows that there is about 0.2% difference between my result and what you got from photoshop
Maybe this way of working will help you get there - or at least explain the problem:
convert xc:"rgba(255,0,0,1)" xc:"rgba(0,0,0,1)" xc:"rgba(0,0,0,0)" -depth 8 -evaluate-sequence mean txt:
Output
# ImageMagick pixel enumeration: 1,1,65535,srgba
0,0: (21845,0,0,43690) #550000AA srgba(85,0,0,0.666667)
Using IM 6.8.9.4 Q16 or IM 7.0.5.5 Q16 Mac OSX Sierra, this seems to work fine for me:
Make transparent image
convert logo: -transparent white logot.png
Get mean
convert logot.png logot.png logot.png -alpha off -evaluate-sequence mean result.png
magick logot.png logot.png logot.png -alpha off -evaluate-sequence mean result.png
This also seems to work:
convert logot.png logot.png logot.png -channel rgb -evaluate-sequence mean -alpha off result.png
So perhaps you need to upgrade your ImageMagick (and/or libpng?)
Can you post a zip file of some of your input images, so we can test with your images?
One problem that I see is that the PNG images that you provided have black under the transparent areas and not image texture. So when you disable alpha as in my commands above, you see black and the black gets averaged into the final result. Did you use these same PNG images in Photoshop or did you have Photoshop PSD images or some other images that you used and then exported to PNG, which may have put black under the transparent areas. Have you tried using the same PNG images in Photoshop to do the average?
In fact, you have 8-bit color (palette) images, which have one color (black) assigned to be the transparent color.

Resources