Page 1 of 1

.jpg to .png batch conversion with background transparency

Posted: 2017-02-14T14:10:54-07:00
by JEBffej7
Hello - I am brand new to working with ImageMagick, and have run into an issue converting .jpg files to .png files while removing the background. I am able to get the process to work perfectly for single images with the following code (line breaks added for readability):

Code: Select all

convert Image.jpg ( +clone -fx p{0,0} ) -compose Difference -composite -modulate 100,0 -alpha off invertedInamge: png:- | 
convert -threshold 20% threshold_mask: png:- | 
convert Image.jpg -alpha off -compose CopyOpacity -composite Transparent_Image.png
The issue I'm having is turning the code into a batch process. After spending the last couple days searching/reading documentation and other posts, this is as close as I've been able to get:

Code: Select all

convert *.jpg ( +clone -fx p{0,0} ) -compose Difference -composite -modulate 100,0 -alpha off invertedInamge-%d: png:- | 
convert -threshold 20% threshold_mask-%d: png:- | 
convert *.jpg -alpha off -compose CopyOpacity -composite Transparent_Image-%d.png
The resulting image is a single image - a combination of the alphabetically first image, with a combined mask of all the other images applied to it. What am I doing wrong to where the code is producing a single image instead of multiple results?

I am using ImageMagick 7.0.4-8 through the command line interface on a Windows 7 PC.

Thank you in advance for your help!

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-14T15:29:30-07:00
by fmw42
I am not a Windows user, but % as in 20% need to be escaped as 20%% in bat files. See http://www.imagemagick.org/Usage/windows/

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-14T16:28:20-07:00
by GeeMack
fmw42 wrote: 2017-02-14T15:29:30-07:00 I am not a Windows user, but % as in 20% need to be escaped as 20%% in bat files.
Yep. Every percent sign in a BAT script must be doubled to make it work. That would be like "-threshold 20%%" and "Transparent_Image-%%d.png". All of them.

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-14T16:40:34-07:00
by fmw42
You do not need all the pipes. You should be able to do that in one command line with parenthesis processing and clones.

Also your second command syntax is wrong. It should read the input before applying the threshold.

Where are you getting invertedInamge: and threshold_mask:. Those are not internal IM images like logo: and rose:. Sorry I do not understand this syntax. If they are the results from a previous command piped to the new command, then you should just use - for the input of the new command.

Have you tried (I hope correct Windows syntax for terminal not .bat)

Code: Select all

convert Image.jpg ( +clone -fx p{0,0} ) -compose Difference -composite -modulate 100,0 ( +clone -threshold 20% ) -alpha off -compose CopyOpacity -composite Transparent_Image.png

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T09:48:24-07:00
by JEBffej7
Thank you for the response! The code you provided was in the correct syntax, unfortunately I think the order of operations is switched around somewhere (it's applying the background mask to the greyscale image used to originally create the mask, instead of the color image itself, so the final image is masked correctly, but appears in greyscale). Also, when I changed the input from Image.jpg to *.jpg, and the output name to Transparent_Image-%d.png, I still encountered the same issue I was having earlier with batch conversions, where only one image is returned.

The advice about not having to pipe the commands together was helpful! I am going to keep researching and trying to get the batch conversion to work using your example as a starting point. If you have any other suggestions, I'd be grateful!

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T10:16:42-07:00
by snibgo
JEBffej7 wrote:Also, when I changed the input from Image.jpg to *.jpg ...
The command starts by reading an image, "+clone" makes a copy of the last image in the list, and finding the difference.

If, instead, you start by reading a number of images, cloning the last, and "-composite" only works with a pair of images ... well, it won't do what you want.

The easiest way to make it work is to run the command within a shell "for" loop.

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T10:40:56-07:00
by fmw42
As I said before, I do no understand your use of colon in for example invertedInamge: png:-. What is invertedInamge:? There is no such internal IM image like logo: and rose: with the name invertedImage:. The color is a special character in IM that means an internal image or pseudoimage.

What are you trying to do? Perhaps you could post an example input image and output image. Then I can correct the command, if needed, and then you can put that command in a loop over all the images you want to apply.

You can upload images to any free hosting service such as dropbox.com and put the URL(s) here.

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T11:05:56-07:00
by JEBffej7
Essentially, I am trying to take an image like this (.jpg with a non-transparent background):
Image

Render the background and any other white elements transparent, and save it as a .png. The end result looking like this:
Image

The original code came out of working through the three examples here:

https://www.imagemagick.org/Usage/masking/#difference

I also looked through other related examples on how to use the | character to combine separate convert functions. The syntax of invertedInamge: png:- replaced invertedImage.png when being used before a | (I don't remember where I saw this, but it allowed my code to work when using invertedImage.png directly before a | had previously been causing it to fail).

Thank you again for your help and patience!

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T11:45:00-07:00
by fmw42
Here are two ways to do it. The first is your way with my modifications to make it one command line. I use the in-memory mpr:img (rather than another clone) to store your input image to use at the end.

Code: Select all

convert Alligator11_ImageMagick.jpeg -write mpr:img ^
( +clone -fx "p{0,0}" ) -compose Difference -composite -modulate 100,0 ^
( +clone -threshold 20% ) ^
-delete 0 ^
mpr:img +swap -alpha off -compose CopyOpacity -composite result1.png

The second is much simpler I tell IM to convert every pixel that is within 20% of white to transparent. The 20% here is the equivalent of your -threshold 20%

Code: Select all

convert Alligator11_ImageMagick.jpeg -fuzz 20% -transparent white result2.png

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T11:48:07-07:00
by fmw42
I also looked through other related examples on how to use the | character to combine separate convert functions. The syntax of invertedInamge: png:- replaced invertedImage.png when being used before a | (I don't remember where I saw this, but it allowed my code to work when using invertedImage.png directly before a | had previously been causing it to fail).
To pipe an image you do not need somename: and gif:-, you only need the gif:- (or typically one uses miff:-)

Code: Select all

convert image <some processing> gif:- | convert - <some processing> result

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T13:17:44-07:00
by JEBffej7
Thank you! The first code example does exactly what I need it to do for a single image. Unfortunately when I tried converting it to a batch process, it still combined all of the .jpg images in the folder into a single .png

Code: Select all

convert *.jpg -write mpr:img ^
( +clone -fx "p{0,0}" ) -compose Difference -composite -modulate 100,0 ^
( +clone -threshold 20% ) ^
-delete 0 ^
mpr:img +swap -alpha off -compose CopyOpacity -composite result-%d.png
The second example you gave is able to batch process without any issues. I think the problem with the first process is that the -composite is causing ALL of the images to be composited, instead of just the selected one. It may be that -composite is just incompatible with this type of background removal technique being used in a batch image processing scenario.

Thanks again for your help!

Re: .jpg to .png batch conversion with background transparency

Posted: 2017-02-15T14:09:51-07:00
by fmw42
You cannot composite more than two images at a time. You are reading all your input images as *.jpg and then compositing. You need to write a script loop over each image separately and not try to do all the image at once.

Also in a .bat file % needs to be escaped as %%