I'm trying to convert a 16 bit greyscale PNG to a raw file. The image size is 640*480.
First, identify:
$ identify image.png
image.png PNG 640x480 640x480+0+0 16-bit PseudoClass 65536c 299KB 0.000u 0:00.000
I'm expecting the result file to be 640*480*2 bytes in size.
Attempt 1:
$ convert image.png -depth 16 image.raw
This gives a file size of 330805 bytes. Its first 16 bytes look like:
0x00000000: 89504E47 0D0A1A0A 0000000D 49484452 .PNG........IHDR
Attempt 2:
$ convert image.png -depth 16 image.rgb
This gives a file size of 1843200 bytes, which is 640*480*2*3.
I'm running imagemagick version 6.7.7-10 on Ubuntu 14.04.
Any ideas?
Updated Answer
It occurred to me since answering you, that there is a simpler method of doing what you want, that takes advantage of ImageMagick's little-used stream
tool, to stream raw pixel data around.
In effect, you can use this command
stream -map r -storage-type short image.png image.raw
which will read the Red channel (-map r
), which is the same as the Green and Blue channels if your image is greyscale, and write it out as unsigned 16-bit shorts (-storage-type short
) to the output file image.raw
.
This is cleaner than my original answer - though should give identical results.
Original Answer
If you write an RGB raw file, you will get 3 channels - R, G and B. Try writing a PGM (Portable Greymap) like this...
convert image.png -depth 16 pgm:-
P5
640 480
65535
<binary data> < binary data>
The PGM format is detailed here, but suffice to say that there is header with a P
followed by a digit describing the actual subtype, then a width and height and then a MAX VALUE
that describes the range of the pixel intensities. In your case, the MAX VALUE
is 65535 rather than 255 because your data are 16-bit.
You can the strip the header like this:
convert image.png -depth 16 pgm:- | tail -c 614400 > file.raw
If you are converting lots of files of different sizes and dislike the hard-coded 614400
, and are using bash
, you can get ImageMagick to tell you the size (height * width * 2 bytes/pixel) and use that like this:
bytes=$(identify -format "%[fx:h*w*2]" image.png)
convert image.png -depth 16 pgm:- | tail -c $bytes > file.raw
gray
might be the format you want:
convert image.png -depth 16 image.gray
This command stores each pixel in 2 bytes and nothing else in the file.
Here I provide a minimal synthetic example: https://superuser.com/questions/294270/how-to-view-raw-binary-data-as-an-image-with-given-width-and-height/978432#978432
.raw
is not really a "pixel only" format: it does contain some metadata: https://en.wikipedia.org/wiki/Raw_image_format#File_contents
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With