Page 1 of 1
Extract low or high bits from an image using convert
Posted: 2012-12-20T13:00:28-07:00
by personalrobert
I have a 16-bit image file and want to create two images/files from it:
- - the low 8 bits only
- the high 8 bits only
How can I do this?
Re: Extract low or high bits from an image using convert
Posted: 2012-12-21T08:51:58-07:00
by snibgo
I haven't tried this, but I expect if you save a 16-bit image to a lossless 8-bit format, you'll get the high 8 bits. Then subtract this from the original to get the low 8 bits.
Re: Extract low or high bits from an image using convert
Posted: 2012-12-21T10:44:18-07:00
by glennrp
I think you could use -fx. I haven't figured out the exact syntax for the low byte, but this works for the high byte of a 16-bit grayscale image:
Code: Select all
convert -colorspace rgb source.txt -fx "((p / 255) * 257)" -depth 8 high8.txt
I tried a few things for the low byte, but there is some weird stuff that makes shifting and masking fail.
Simply using -depth 8 without the -fx doesn't exactly get the high byte because the pixels are rounded somehow (expected 255 becomes 253).
Re: Extract low or high bits from an image using convert
Posted: 2012-12-21T11:27:06-07:00
by fmw42
I really do not understand much about bit-wise processing, but I would have thought something like the following (bit masking) would have worked (though it may need some kind of bit shift perhaps using -evaluate leftshift or rightshift). But unfortunately it only produces a binary result.
# create a 16-bit grayscale image
convert logo: -set colorspace RGB -colorspace gray -depth 16 logo_tmp.png
# use IM -fx with bit-wise and:
convert logo_tmp.png -fx "u & 0000000011111111" -depth 8 logo_tmp_hi.png
Re: Extract low or high bits from an image using convert
Posted: 2012-12-21T12:06:46-07:00
by snibgo
My initial thought was mistaken, because when an 8-bit image is promoted to 16-bit, the high byte is propagated into the low byte, rather than the low bytes being set to zero. Thus #aa becomes #aaaa, not #aa00.
Evaluating with "And" a bitmask seems to work. Windows script:
Code: Select all
>convert -size 1x1 xc:#ffeeaa99bb88 xc:#ffee99aa8877 xc:#001122334455 -append hilo8.tiff
>convert hilo8.tiff txt:
# ImageMagick pixel enumeration: 1,3,65535,srgb
0,0: (65518,43673,48008) #FFEEAA99BB88 srgb(99.9741%,66.6407%,73.2555%)
0,1: (65518,39338,34935) #FFEE99AA8877 srgb(99.9741%,60.0259%,53.3074%)
0,2: ( 17, 8755,17493) #001122334455 srgb(0.0259403%,13.3593%,26.6926%)
>rem Note: #ff00 is 65280; #00ff is 255.
>convert hilo8.tiff -evaluate And 65280 hi.tiff
>convert hi.tiff txt:
# ImageMagick pixel enumeration: 1,3,65535,srgb
0,0: (65280,43520,47872) #FF00AA00BB00 srgb(99.6109%,66.4073%,73.048%)
0,1: (65280,39168,34816) #FF0099008800 srgb(99.6109%,59.7665%,53.1258%)
0,2: ( 0, 8704,17408) #000022004400 srgb(0%,13.2815%,26.5629%)
>convert hilo8.tiff -evaluate And 255 lo.tiff
>convert lo.tiff txt:
# ImageMagick pixel enumeration: 1,3,65535,srgb
0,0: ( 238, 153, 136) #00EE00990088 srgb(0.363165%,0.233463%,0.207523%)
0,1: ( 238, 170, 119) #00EE00AA0077 srgb(0.363165%,0.259403%,0.181582%)
0,2: ( 17, 51, 85) #001100330055 srgb(0.0259403%,0.077821%,0.129702%)
Re: Extract low or high bits from an image using convert
Posted: 2012-12-21T13:37:23-07:00
by snibgo
Yes, this works for real files. Here's a Windows script that chops a file into low and high bytes, then combines them to reconstruct the original, and finally compares this with the orginal (and reports zero difference).
Code: Select all
set SRC=c:\pictures\20121113\AGA_0994_final.tiff
"%IMG%convert" %SRC% ^
( +clone -evaluate And 65280 -write hi.tiff +delete ) ^
-evaluate And 255 lo.tiff
"%IMG%convert" ^
lo.tiff ^
hi.tiff ^
-compose Plus -composite ^
combined.tiff
"%IMG%compare" %SRC% combined.tiff -metric RMSE null:
Re: Extract low or high bits from an image using convert
Posted: 2012-12-21T13:47:23-07:00
by glennrp
This worked. I couldn't get -fx to extract the low byte properly so used a combination of -evaluate and -fx:
Code: Select all
convert -size 256x1 \
gradient:'#ff000000ff00'-'#00ff000000ff' \
source.txt
# to test grayscale use "gradient:'#ff00ff00ff00'-'#00ff00ff00ff'" instead.
convert source.txt -fx "(((p-(.5/256)) / 255) * 257)" -depth 8 high8.txt
convert source.txt -evaluate and 255 -fx "(p * 257)" -depth 8 low8.txt
echo high8.txt:
cat high8.txt
echo low8.txt:
cat low8.txt
Re: Extract low or high bits from an image using convert
Posted: 2012-12-22T03:47:51-07:00
by Bonzo
When I see posts like this I always think "Why would the poster want to do this".
Out of interest why would you want to do this?