.jpg to .png batch conversion with background transparency

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
JEBffej7
Posts: 4
Joined: 2017-02-14T13:51:08-07:00
Authentication code: 1151

.jpg to .png batch conversion with background transparency

Post 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!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

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

Post 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/
User avatar
GeeMack
Posts: 718
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

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

Post 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.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

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

Post 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
JEBffej7
Posts: 4
Joined: 2017-02-14T13:51:08-07:00
Authentication code: 1151

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

Post 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!
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

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

Post 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.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

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

Post 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.
JEBffej7
Posts: 4
Joined: 2017-02-14T13:51:08-07:00
Authentication code: 1151

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

Post 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!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

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

Post 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
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

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

Post 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
JEBffej7
Posts: 4
Joined: 2017-02-14T13:51:08-07:00
Authentication code: 1151

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

Post 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!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

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

Post 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 %%
Post Reply