Calculate the main memory consumption of ImageMagick convert when appending images - imagemagick

I append several PNG images with the ImageMagick convert tool.
convert -set colorspace RGB `ls *.png` -append outout.png
This are the color parameters of the input files:
$ identify input1.png
input1.png PNG 9600x1800 9600x7200+0+0 8-bit sRGB 355KB 0.000u 0:00.000
4 input files exist with identical parameters.
The output file has these color parameters:
$ identify output.png
output.png PNG 9600x7200 9600x28800+0+0 8-bit sRGB 2.461MB 0.000u 0:00.009
This is the ImageMagick version I use:
$ convert -version
Version: ImageMagick 6.7.7-10 2014-04-09 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP
How can I calculate the main memory consumption of the convert ... -append operation?

It seems you are using the Q16 version of ImageMagick and this version of ImageMagick uses 16 bits per pixel channel (The Q8 version uses 8 bits per pixel). In ImageMagick 6 each pixel has 4-5 channels per pixel (red,green,blue,opacity, index), this behavior is going to change in ImageMagick 7 (http://www.imagemagick.org/script/porting.php#channels). Since your input and output are both a png file you are using 4 channels per pixel, this totals to 16*4 = 64 bits per pixel. Because your input images are 9600x1800 and you are combining 4 of them into a single image you will need a total of 64*9600*1800*4 = 4423680000 bits / 552.96 MB to allocate the images in memory. But because a copy of each image is created when the output image is created you will need twice that amount of memory: 1.1 GB.

Related

How to convert PNG images (specifically grayscale ones) to Indexed color

I'm trying to convert some small PNG images from 32-bit color mode to indexed color mode.
For color images, I ran the command convert IMGS/FLAME.png INDEXED_IMGS/FLAME.png and it converted fine. For an image that had only grayscale colors, I ran that same command (with the filename changed obviously) but I got a warning:
convert: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG 'INDEXED_IMGS/SHADOW.png' # warning/png.c/MagickPNGWarningHandler/1748.
I ran file IMGS/*.pngand got
IMGS/FLAME.png: PNG image data, 16 x 16, 8-bit/color RGBA, non-interlaced
IMGS/SHADOW.png: PNG image data, 8 x 8, 8-bit/color RGBA, non-interlaced
which is expected; both images are in 8-bit RGBA mode (since that's the mode I created them in Photoshop). However, when I run file INDEXED_IMGS/*.png I get
INDEXED_IMGS/FLAME.png: PNG image data, 16 x 16, 4-bit colormap, non-interlaced
INDEXED_IMGS/SHADOW.png: PNG image data, 8 x 8, 8-bit grayscale, non-interlaced
The 4-bit colormap part checks out, but the grayscale part does not.
So my question is: how can I convert a grayscale image to indexed mode? What really gets me is that it starts out in RGBA mode like the color image, but for some reason it converts automatically to grayscale mode. Is there a way to prevent it from doing that?
I should add that I have a bash script that looks like this:
#!/bin/bash
for img in IMGS/*.png; do
file=$(basename $img)
convert $img INDEXED_IMGS/$file
done
so I don't wanna manually distinguish between grayscale and colored images. If there's a way to do so automatically with some command that's fine though.
Here is info about my ImageMagick tool:
Version: ImageMagick 7.0.8-42 Q16 x86_64 2019-04-24 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP
Delegates (built-in): bzlib freetype heic jng jp2 jpeg lcms ltdl lzma openexr png tiff webp xml zlib
With ImageMagick, for 24-bit color, append the output with PNG8:output
convert input.png PNG8:output.png
PNG grayscale images do not support color profiles, so you get that warning. But the resulting image should be 8-bit palette.
If you have 32-bit color, then this needs more to be done. The color under the alpha channel must be one constant color and one not used elsewhere in the image. Find such a color after converting to 256 colors and set the color under the transparency to that color. For example if you have no opaque black in your image after converting to 256 colors, then set the alpha base color to black.
convert image.png +dither -colors 256 -background black -alpha background PNG8:output.png
You can get a list of unique colors from the image as follows:
convert image.png +dither -colors 256 -unique-colors txt:
Here is an example:
Make it 32-bit transparent:
convert rose.png -fuzz 20% -transparent red rose_trans32.png
identify -verbose rose_trans32.png
...
Colorspace: sRGB
Type: TrueColorAlpha
...
Convert to palette alpha:
convert rose_trans32.png -alpha off +dither -colors 256 -unique-colors txt:
List shows no black
convert rose_trans32.png +dither -colors 256 -background black -alpha background PNG8:rose_trans8.png
Or if you already know that the 32-bit version has not black, then just:
convert rose_trans32.png -background black -alpha background PNG8:rose_trans8.png
identify -verbose rose_trans8.png
...
Colorspace: sRGB
Type: PaletteAlpha
...
If you do this adding -colorspace gray, ImageMagick will still report as type grayscalealpha, since it recognizes it as a single channel image with transparency. But using EXIFTOOL, it will report 9 ColorType: 3, which is 3 = RGB Palette
NOTE: For ImageMagick 7, change convert to magick.

How do I convert EXR to PNG and adjust brightness at the same time

I was able to convert my EXR image to a PNG using the techniques outlined in Image conversion from IFF and EXR formats to JPEG format .
convert 0007.exr /tmp/0007.png
Unfortunately the PNG looks quite dim.
What should I add to the imagemagick convert command line to increase the brightness?
Starting with this:
You could try -auto-gamma:
convert start.jpg -auto-gamma result.jpg
If the -auto-gamma overcooks the image for your liking, you could apply a percentage of it. So, here I clone the original image and apply auto-gamma to the clone but then only blend 80% back into the original because I feel auto-gamma overdoes it:
convert start.jpg \( +clone -auto-gamma \) \
-define compose:args=80 -compose blend -composite result.jpg
Or, another option, you could experiment with your particular images and maybe try using -modulate for the brightness, where 100% means "do nothing", so numbers over 100 increase the brightness:
convert start.jpg -define modulate:colorspace=LCHuv -modulate 160 result.jpg
You can try -auto-level, which will take the minimal value and the maximal value of your picture and then stretches the values to the full range of values:
convert input.exr -auto-level output.jpg
Note that if you picture was too bright and this does not help, then it might be that your image is stored with 32 Bit, while ImageMagick is working with 16 Bit and no HDRI support. 32 Bit input is supported if convert --version
either show Q32 as part of the version string or lists HDRI under features.
Depending on your operating system you might be able to install another variant of ImageMagick. For example, for Debian Buster we can use sudo apt list imagemagick* to see that the package imagemagick-6.q16hdri is available. Installing this package provides convert-im6.q16hdri, which allows reading 32 Bit EXR images.
EXR is in linear RGB colorspace. You want to convert it to non-linear sRGB colorspace in Imagemagick as:
Input:
convert image.exr -set colorspace RGB -colorspace sRGB output.png

ImageMagick Convert BMP from 24 bit to 16 bit Mode?

I am trying to convert a BMP from 24 bits/pixel to 16 bit/pixel Mode in ImageMagick.
convert /tmp/a/new/37.bmp -depth 5 -define bmp:format=bmp2 /tmp/a/new/37_v2_16bit.bmp
convert /tmp/a/new/37.bmp -depth 5 -define bmp:format=bmp3 /tmp/a/new/37_v3_16bit.bmp
The result has the same 8 bit per R., per G. and per B., according to output of:
identify -verbose
What am I doing wrong? How to get 16-bit color in BMP ?
Thank you!
P. S.
-depth value
depth of the image. This is the number of bits in a pixel. The only acceptable values are 8 or 16.
http://linux.math.tifr.res.in/manuals/html/convert.html
=(
Official Documentation says (no restrictions mentioned):
-depth value
depth of the image.
This the number of bits in a color sample within a pixel. Use this option to specify the depth of raw images whose depth is unknown such as GRAY, RGB, or CMYK, or to change the depth of any image after it has been read.
convert /tmp/a/new/37.bmp -colors 256 /tmp/a/new/37_256.bmp
makes the file smaller, but visually it is the same! wth?! )))))
convert /tmp/a/new/37.bmp -colors 65536 /tmp/a/new/37_64k.bmp
same size, same visual picture.
convert /tmp/a/new/37.bmp -dither None -colors 256 /tmp/a/new/37_256_nd.bmp
a bit smaller again, but it does not look like 256-colored! bug? 256 colored 800x600 BMP is ~ 800x600x1 Bytes (without headers) ~ 480 000 Bytes. But it says ~650 000 Bytes)))) funny program))
The documentation you quoted from linux.math... is pretty old (2001) and is incorrect about -depth. The "-depth 16" option does not mean 16-bit pixels (like R5G6R5 or R5G5R5A1); -depth 16 means 48-bit/pixel R16, G16, B16 or 64-bit/pixel R16, G16, B16, A16 pixels. The "Official documentation" that you quoted (2015) is correct.
ImageMagick doesn't support that kind of 16 bit/pixel formats, so you'll need to store them in an 8 bit/channel format and live with the larger filesize.
It also appears that for images with 256 or fewer colors, it will write a colormapped image with 1, 4, or 8-bit indices. You don't have to make any special request, it'll do that automatically. Use "-compress none" for uncompressed BMP's. The current ImageMagick (version 6.9.2-8) gives me the expected 480kbyte file if I start with an 800x600 image with more than 256 colors and use
convert im.bmp -colors 256 -compress none out.bmp
ImageMagick does support a 16-bit "bitfields" BMP format while reading but I don't see any indication that it can write them, and haven't tried either reading or writing such images.
It's not ImageMagick but ffmpeg, more associated with video, can create a 16bit bmp image if you are referring to the 565 format?
ffmpeg -i ffmpeg-logo.png -sws_flags neighbor -sws_dither none -pix_fmt rgb565 -y ffmpeg-logo-16bit-nodither.bmp
That intentionally disables dithering but if you want that just omit the sws parts, e.g.
ffmpeg -i ffmpeg-logo.png -pix_fmt rgb565 -y ffmpeg-logo-16bit-dithered.bmp
If your images are inherently from an rgb565 source then it should not dither them but I'd always be cautious and inspect a few closely before doing any batch conversions.
Based on the discussion in the comments it sounds like PNG would be a good format for preserving old screenshots verbatim as it uses lossless compression but maybe that's not applicable due to use with vintage software?

Incorporating a grayscale TIFF as alpha channel in another TIFF with ImageMagick

When I scan negatives Sane provides 16-bit grayscale files containing infrared information along with the 48-bit RGB files that contain the image information.
Is there any way to combine these two files using ImageMagick in order to obtain a 64-bit RGBA TIFF file whose Alpha channel (infrared) is somehow recognized in Photoshop? Photoshop may detect it as transparency, separate layer or even outright Alpha channel. All these are fine by me.
I haven't been able to obtain much following numerous ImageMagick tutorials on the internet. All TIFFs I get are devoid of transparency information. Libtiff's tiff2rgba does not seem to be of much help either.
My ImageMagick version information:
$ convert --version
Version: ImageMagick 6.8.8-6 Q16 x86_64 2014-02-17 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC
Delegates: bzlib fftw fontconfig freetype jng jpeg lcms lzma png tiff webp x xml zlib
I am not 100% certain I have got your filetypes and needs exactly understood, but if I create a red square TIFF like this:
convert -size 512x512 xc:red rgb.tiff
and a synthetic (faked) greysale gradient to represent your IR image, like this:
convert -size 512x512 -colorspace gray gradient:\#000000-\#ffffff ir.tiff
I can combine them using the IR as opacity like this:
convert rgb.tiff ir.tiff -compose copyopacity -composite out.tiff
to give this, which at least my version of Photoshop CC 2014 understands.
By the way. it seems equally happy creating a Photoshop PSD format directly:
convert rgb.tiff ir.tiff -compose copyopacity -composite out.psd

ImageMagick: convert keeps changing the colorspace to Gray. How to preserve sRGB colorspace?

I have a batch script that converts my PNG-24 (with Transparency) images to 50% and 25% size (for mobile development). Usually these images have colors in them but now I am trying to convert an image that has no colors and ImageMagick keeps changing the colorspace profile to "Gray", which messes up my image in the 3d engine I'm using (Unity).
I have tried forcing it to use type TrueColor, colorspace sRGB, and the sRGB.icc profile (the one included with OSX) but it doesn't seem to care. It still changes it to Gray.
> convert old.png -profile srgb.icc -colorspace sRGB -type TrueColor new.png
> identify *.png
old.png PNG 140x140 140x140+0+0 8-bit sRGB 3.68KB 0.000u 0:00.000
new.png PNG 140x140 140x140+0+0 8-bit sRGB 256c 2.33KB 0.000u 0:00.000
ImageMagick still identifies it as an 8-bit sRGB image but it puts "256c" after it which I'm assuming means it has reduced it down to 256 colors, which I don't want either. When I look at the image in OSX Preview.app, it says it is using the Gray color profile. The image also visually looks a lot different.
Here is the image I'm using: https://dl.dropbox.com/u/59304/old.png
There is a duplicate question here, ImageMagick Reduces Colorspace to Gray, but the answer does not work for me and I don't have enough reputation to comment on his answer, unfortunately. I imagine my case is different because I'm using PNG and not JPG.
Version: ImageMagick 6.8.0-7 2013-01-02 Q16 http://www.imagemagick.org
Features: OpenCL
edit- After reading the ImageMagick forums as specified in one of the answers, it looks like just prepending PNG32: or PNG24: to the output file solves the problem.
The proper way to keep a grayscale PNG as RGB is to use PNG24:result.png
Input:
convert lena.png -colorspace gray PNG24:lenag_rgb.png
identify -verbose lenag_rgb.png
Image: lenag_rgb.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 256x256+0+0
Units: Undefined
Colorspace: sRGB
Type: Grayscale
So as you see above, Colorspace is RGB while the type is Grayscale.
For other image formats such as JPG and TIFF, use -define colorspace:auto-grayscale=false along with -type truecolor.
You may pass -set colorspace:auto-grayscale off to convert to disable automatic conversion of RGB channels to a single grayscale channel.
This solution was not yet available at the time of your question, but was introduced in 2015 with version 6.9.2:
2015-07-25 6.9.2-0 Dirk Lemstra <dirk#lem.....org>
Added -set colorspace:auto-grayscale=false that will prevent automatic conversion to grayscale inside coders that support grayscale.

Resources