Preserving PNG transparency during a simple transformation in imagemagick - image-processing

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

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.

Compose image with mask image using ImageMagick

Suppose I have some image a.jpg and some other image b.jpg.
The desired output out.jpg should be obtained by copying all the pixels from b.jpg that are not black onto a.jpg, all other pixels shall remain untouched.
I tried using composite but had no success whatsoever.
EDITED TO ADD: A solution here can be quite simple and generic, but going forward, please remember to always include your version of ImageMagick and which OS or platform you're working on. There are some syntax differences that can make that important.
At the very simplest, using ImageMagick v6, you should be able to do something like this...
convert b.jpg -background none -transparent black a.jpg +swap -composite out.jpg
That reads in the B image, changes all the pure black pixels to transparent, then reads in the A image, swaps the images so they're in the right order, then composites the modified B image over the A image and writes the output.
You can add a fuzz value like "-fuzz 5%" ahead of the "-transparent" operation to expand the selection to include near-black pixels, also.
To use with IMv7 change "convert" to "magick".

ImageMagick removes colors when alpha is 0 (png)

I am converting many 3D textures with imagemagick for a video game. My source files are png, my target files are png, too. But I notice that whenever the alpha channel drops to 0.0 my color information are gone (and I need them). I just want to scale all channels as they are. I guess there is a small switch that fixes that problem, but the deadline is near and I cannot find anything about that.
Simple command to reproduce this:
convert source-with-alpha.png -scale 2014 target.png (I also tried -resize and it also didn't work).
Doing just convert source-with-alpha.png target.png works fine though (but has no scaledown).
Thank you for your help.
I guess ImageMagick is trying to optimise something but not sure what/why. Maybe the idea is that if something is transparent you can't see it, so we might as well make it black so it compresses well.
Anyway, try separating the channels so they are all just treated as independent channels, then resizing and recombining:
convert input.png -channel RGBA -separate -resize XxY -combine result.png
I am not sure I understand your problem. I have no issue resizing a transparent PNG image with ImageMagick 6.9.10.28 Q16 Mac OSX with libpng 1.6.36. Perhaps you need to upgrade one or both.
Image:
Make white into transparent:
convert logo.png -transparent white logot.png
Resize it:
convert logot.png -resize 25% logot_small.png
I tried Mark Setchell answer with two different versions of Windows imagemagick but I still have this issue.
RGB becomes 0 if alpha is 0 when resizing.
A workaround was to add alpha a little bit so it becomes non-zero:
magic.exe input.tga -channel a -evaluate add 0.2% -channel RGBA -separate -filter Quadratic -resize -resize XxY! -combine result.tga
or also (same result)
magick.exe ( input.tga -alpha off -filter Quadratic -resize XxY! ) ( input.tga -filter Quadratic -resize XxY! -alpha extract -evaluate add 0.2% ) -compose Copy_Alpha -composite result.tga
("-filter Quadratic" is optional)
Post one of your tga files so we can test with it. What is your ImageMagick version? There should be no need for any switch. This works fine for me on IM 6.9.10.65 Q16 Mac OSX.
Make a transparent TGA:
convert logo: -transparent white logo.tga
transparent tga image
Resize by 50%
convert logo.tga -resize 50% logo2.tga
resized transparent tga image

How to replace white background color with transparent of an image in 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

ImageMagick: lay a partly transparent tile over an image

I have a wallpaper.jpg (size: 1920x1280) and a partly transparent tile.gif (size: 16x16).
On a website I want to have the tile as a x- and y-repeated overlay over the wallpaper.
Right now, this overlay is realized using CSS. I want to save one request and merge the (repeated) tile.png with the wallpaper.jpg using ImageMagick. The wallpaper.jpg is generated via ImageMagick anyway.
Following the Documentation of the -tile option, I came up with the following command:
convert wallpaper.jpg -size 1920x1280 tile:tile.gif -compose over -composite result.jpg
The result, however, is a 1920x1280 jpg filled with the tile, but no wallpaper shining through. Instead, the transparent part of the tile seem to be white.
The documentation says:
If the tile image is partially transparent then a 'Over' "-compose" method will need to be specified.
So what's wrong?
I also tried -flatten instead of -composite... same result.
edit:
I realize, there is also another -tile option documentation. It seems to follow the concept of overloading. Unfortunately, I cannot figure out how to use it correctly.
This should do the trick:
convert wallpaper.jpg -background none -size 1920x1280 tile:tile.gif -composite result.jpg
(you can also add -compose over, but that should not make any difference).
Not sure if it will help, but have you tried converting your tile.gif to a 24-bit PNG file with Alpha/Transparency? - Scratch that....
I found some example showing but am unsure about the full command line:
composite -tile tile.gif netscape: wallpaper.jpg
Source: http://www.imagemagick.org/Usage/compose/#tile

Resources