[magick-users] Converting 16-bit GRAY files to 8 bits
Anthony Thyssen
A.Thyssen at griffith.edu.au
Mon Feb 2 22:35:43 PST 2009
On Mon, 02 Feb 2009 22:11:54 -0500 (Eastern Standard Time)
Robert Funnell <robert.funnell at mcgill.ca> wrote:
| On Tue, 3 Feb 2009, Anthony Thyssen wrote:
|
| > On Mon, 02 Feb 2009 07:16:38 -0500 (Eastern Standard Time)
| > Robert Funnell <robert.funnell at mcgill.ca> wrote:
| >
| > | On Mon, 2 Feb 2009, Anthony Thyssen wrote:
| > |
| > | > On Sun, 01 Feb 2009 08:58:36 -0500 (Eastern Standard Time)
| > | > magick-users-bounces at imagemagick.org wrote:
| > | >
| > | > | I am trying to convert 16-bit GRAY files to 8-bit JPEG or PNG format.
| > | > | Since the original images are actually 12-bit, I assume that I need to
| > | > | right-shift each pixel, so I'm using a command like
| > | > |
| > | > | convert -size 512x512+3416 -depth 16 -evaluate RightShift 4 -endian LSB gray:c_vf1169.fre c_vf1169_rs4_lsb.png
| > | > |
| > | > | The effect seems to be that the high-order byte is simply ignored when
| > | > | the right-shift is done. Could someone please explain what I'm doing
| > | > | wrong? I'm using IM 6.2.4 Q16 as distributed by Debian.
| > | > |
| > | > | I apologize if this is really obvious, but I haven't been able to
| > | > | figure it out or find an answer.
| > | > |
| > | > perhaps the 12 bit values in 16 bit integers are already left shifted?
| > |
| > | The 12 bits are indeed right shifted in their 16-bit representation.
| > | What I wanted to do was to right shift the 12 bits into an 8-bit value
| > | for use in an 8-bit PNG.
| > |
| > | In looking into this further in response to your response, I've
| > | discovered that PNG does support 16-bit greyscale, but I don't want
| > | that. I've tried some additional manoeuvres but without success, and I
| > | haven't figured out how to tell IM whether to produce 8-bit or 16-bit
| > | PNG.
| > |
| > | - Robert
| > |
| > Note that IM will only use the most significate bits if the output image
| > format is only using 8 bits values. So you will not need to right shift
| > them.
|
| I'm a bit confused by this. Are you saying:
| 'Note that IM will use only the 8 most significant bits if the output
| image format is using 8-bit values'?
|
| > That is if the 12 bit value are currently converted to 16 bit values
| > either by -evaluate LeftShift, or by IM itself. then IM will handle
| > any further processing correctly.
|
| Under what circumstances would IM convert the 12-bit value to 16 bits
| 'by itself', without my doing a LeftShift?
|
| > Try saving using -depth 8 output.png
| > or using png8:output.png for a 8bit palette PNG image.
|
| If I understand you correctly, I should do
| convert -size 512x512+3416 -endian LSB -depth 16 -evaluate LeftShift 4 gray:c_vf1169.fre -depth 8 c_vf1169_ls4_lsb.png
|
Almost....
read the image then do the evaluate on it.
convert -size 512x512+3416 -endian LSB -depth 16 gray:c_vf1169.fre \
-evaluate LeftShift 4 \
-depth 8 -type Grayscale c_vf1169_ls4_lsb.png
Each line is one operation.
However for testing I would
1/ use a smaller image segment
2/ output to say txt: so you can see what the actual values are
3/ see what effect the evaluate has until I get it right.
For example assuming single white pixel 12 bit value is input...
perl -e 'print pack('v', 2**12-1)' > one_white.gray
then convert and just output the image as a text file...
convert -size 1x1 -endian LSB -depth 16 gray:one_white.gray \
txt:-
I get...
# ImageMagick pixel enumeration: 1,1,65535,rgb
0,0: ( 4095, 4095, 4095) #0FFF0FFF0FFF rgb(6.24857%,6.24857%,6.24857%)
which is obviously not 'white'.
So.. lets Left shift it.
convert -size 1x1 -endian LSB -depth 16 gray:one_white.gray \
-evaluate LeftShift 4 txt:-
# ImageMagick pixel enumeration: 1,1,65535,rgb
0,0: (65520,65520,65520) #FFF0FFF0FFF0 rgb(99.9771%,99.9771%,99.9771%)
well that is 'near white' so that should produce a pretty good
white pixel image for any format you care to output it at.
convert -size 1x1 -endian LSB -depth 16 gray:one_white.gray \
-evaluate LeftShift 4 -depth 8 txt:-
# ImageMagick pixel enumeration: 1,1,255,rgb
0,0: (255,255,255) #FFFFFF white
PERFECT!
Of course a better solution would be to multiply the image by the
appropriate amount to convert 2^12-1 into 2^16-1
perl -e 'print( (2**16-1)/(2**12-1), "\n")'
16.003663003663
this should fill in the lower order bits appropriately to make
a perfectly depth scaled 16 bit image!
convert -size 1x1 -endian LSB -depth 16 gray:one_white.gray \
-evaluate Multiply 16.003663003663 txt:-
# ImageMagick pixel enumeration: 1,1,65535,rgb
0,0: (65535,65535,65535) #FFFFFFFFFFFF white
Good. trying a perfect grey...
perl -e 'print pack('v', 2**11-1)' > one_gray.gray
convert -size 1x1 -endian LSB -depth 16 gray:one_gray.gray \
-evaluate Multiply 16.003663003663 txt:-
# ImageMagick pixel enumeration: 1,1,65535,rgb
0,0: (32759,32759,32759) #7FF77FF77FF7 rgb(49.987%,49.987%,49.987%)
Not a perfect 16-bit gray, but it is the closest you get at 12 resolution.
| It doesn't work, but if you say that that's what I should be doing
| then I'll explore the pixel bits some more.
|
Basically what I was saying was... get the image input right,
and IM will handle everything else right!
It is just a matter of how 'correct' you want that input :-)
Anthony Thyssen ( System Programmer ) <A.Thyssen at griffith.edu.au>
-----------------------------------------------------------------------------
I've heard of hunt-and-peck typing,
but his is more search-and-destroy!
-----------------------------------------------------------------------------
Anthony's Home is his Castle http://www.cit.gu.edu.au/~anthony/
More information about the Magick-users
mailing list