Depth Splitting

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
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Depth Splitting

Post by jmac698 »

Hi,
I want to convert a 16bit image to a stacked 8 bit image. I can do it like this:

Code: Select all

convert IMG_7853.png ( +clone -evaluate and 255 -evaluate multiply 256 ) -evaluate and 65280 -append -depth 8 test.png
This puts the high bits at the top and low bits at the bottom.

Now I want to do the opposite. I know it's some combination of -crop 100%x50% and -compose plus -composite, but I can't quite figure it out. First problem: when I do

Code: Select all

convert test.png -crop 100%x50% test1.png
I get two images, the top half and bottom half. I don't understand the stack well enough to know how to process index0 on the stack one way and index1 the other way, also I don't see why crop gives me a cropped part and the rest of the image, I thought it would give just one image.

Then, once I process each subimage (basically -evaluate multiply 256 on the first and nothing on the second), I want to merge the two images by just adding them. I'm not sure if it'll automatically create a 16bit image and it's only a matter of saving it, or if I need a -depth 16 in there somewhere.

If I can get this far, the next problem is converting a whole directory of images to my stacked format, but piping it to another program as an animated png or something with multiple pages, that I can read in another video editing program. Then I need to know how to accept a pipe of raw frames and convert them back to 16bit pngs. It's a bit complicated, I'll have to explain later.

Thanks for your help.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Depth Splitting

Post by snibgo »

"-crop 100%x50%+0+0" would give you one image. Omitting "+0+0" gives you one image, and the reminder in a second.

I guess you are using Q16? When you read 8-bit images, they are automatically promoted to 16-bit by replicating the byte. For example, a byte #5a would become the 16-bit value #5a5a.

So I think your reverse process wants to add the high byte from one image and the low byte from the other. Something like this (untested):

Code: Select all

convert in.png
  -crop 100%x50%
  ( -clone 0 -evaluate and 65280 )
  ( -clone 1 -evaluate and 255 )
  -delete 0-1
  -compose Add -composite
  out.png
Adjust the syntax as required for your shell language.
snibgo's IM pages: im.snibgo.com
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Re: Depth Splitting

Post by jmac698 »

Thanks for your reply, you gave me some hints. I've made progress, but this still isn't right:

Code: Select all

convert test.png -depth 16 -crop 100%x50% ( -clone 0 ) ( -clone 1 -evaluate multiply 256 ) -delete 0-1 -compose Add -composite -define png:bit-depth=16 test1.png
One thing I've noticed, is the endian seems to be swapped, that is the high byte is getting displayed as the low bits. There's some extra something being added in, but I just realized what you said about replicating bytes, I think that's the problem, so I have to AND that out.
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Re: Depth Splitting

Post by jmac698 »

I found a bug!

Code: Select all

convert -size 400x400 canvas:white ( +clone -evaluate set 32768 ) ( +clone -evaluate set 16384 ) -delete 0 -append stacked.png
convert stacked.png -crop100%x50% -depth 16 ( -clone 0 -evaluate multiply 2 ) ( -clone 1 -evaluate multiply 256 ) -delete 0-1  -compose Add -composite -define png:bit-depth=16 test1.png
http://imgur.com/K9AifJL
jmac698
Posts: 48
Joined: 2013-12-20T01:57:16-07:00
Authentication code: 6789

Re: Depth Splitting

Post by jmac698 »

convert stacked (high/low) to 16bit:

Code: Select all

convert stacked.png -depth 16 -crop 100%x50% ( +clone -evaluate divide 256 ) -delete 1 -compose Add -composite -define png:bit-depth=16 16bit1.png
convert 16bit to stacked (high/low):

Code: Select all

convert 16bit.png -depth 16 ( +clone -evaluate and 255 -evaluate multiply 256 ) -append stacked.png
It took a long time to figure this out. Some important points I had to understand: with -depth 16, all processing is done in 16bit. 8bit images are read as 0xNN00, that is, the pixels are moved to the high byte. When converting 16bit back to 8bit, the high byte is kept (no rounding or dithering). Next, all options are applied to the source image, then the sub images (operations in parentheses) are applied. ( +clone ) will set the image source as the subprocessing source. If you do two suboperations, use ( +clone 0 ) or else you will work on the last item in the stack, which will be the previous subprocessing result. The crop command put two items on the stack, the cropped result and the rest of the image.

This stacked format is used for processing with Avisynth http://avisynth.nl/index.php/Stack16

For a full explanation of the command line, see http://forum.doom9.org/showthread.php?t=172846
Post Reply