Page 1 of 2

Convert 2-bit to png after deskew has odd results

Posted: 2018-02-16T10:45:50-07:00
by muccigrosso
I've got an image in pgm format which identify says is "1-bit Bilevel Gray". If I convert it directly to png, it's fine. identify reports the png as "8-bit Gray 2c". Looks the same, of course.

Now, if I "-deskew 40%" that image, the png is still "8-bit Gray 2c", but clearly a bunch of the pixels have turned white from black. This does not happen if I just do a deskew and then show: the result. Nor does it happen if I convert to jpg or force the image depth with "-depth 8". If I deskew and save back to pgm, I have to set "-compress none" or I get a black image. In that case identify reports "8-bit Grayscale Gray".

I assume what's happening is that the deskew creates some gray pixels, so if I have an output format with enough depth those will show up. Is that right?

Here's what I definitely don't understand:
  • The output png is 8-bit, but the pixels get forced to 2 colors. Why? Is IM trying to maintain the original depth from the pgm?
  • Why does the deskewed pgm look OK with show: then? Does that forceIM to use as many colors as needed?

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-16T11:01:53-07:00
by fmw42
What is your IM version and platform? Can you provide your exact command line and your input and output results? You can post them to some free hosting service such as dropbox.com and put the URLs here.

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-16T11:05:33-07:00
by snibgo
muccigrosso wrote:Is IM trying to maintain the original depth from the pgm?
Yes.
muccigrosso wrote:Why does the deskewed pgm look OK with show: then?
Because the small bit depth (2) is used when writing PNG, not when writing to "show:".

To cure the problem, use "+depth" to get the full depth of the Q-number, or "-depth 8" or 16 or whatever.

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-16T11:13:53-07:00
by muccigrosso
MacOS 10.13.3
ImageMagick 7.0.7-22 Q16 x86_64 2018-01-23

Commands are:
  • convert -deskew 40% test.pgm test_deskew.png
  • convert -deskew 40% test.pgm test_deskew.jpg
  • convert -deskew 40% -depth 8 test.pgm test_depth.png
  • convert -deskew 40% test.pgm show:
Files are here: https://www.dropbox.com/s/ecuuyke92d661lz/files.zip

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-16T11:18:02-07:00
by muccigrosso
snibgo wrote: 2018-02-16T11:05:33-07:00
muccigrosso wrote:Why does the deskewed pgm look OK with show: then?
Because the small bit depth (2) is used when writing PNG, not when writing to "show:".

To cure the problem, use "+depth" to get the full depth of the Q-number, or "-depth 8" or 16 or whatever.
Thanks.

Is the +depth option documented somewhere?

I'd have expected IM to maintain the new depth after deskew alters the image. Why does it do that?

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-16T11:48:28-07:00
by snibgo
"+depth" doesn't seem to be documented, except in these forums. (@Fred: can you add a note to http://www.imagemagick.org/script/comma ... .php#depth ?)

The depth setting is used only when writing output. It has no effect on other processing. The depth setting is set by the input image, and doesn't change unless "-depth" or "+depth" is used.

(Users sometimes assume that IM automatically writes outputs using whatever depth is required to maintain precision. But IM doesn't work like that.)

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T10:53:18-07:00
by muccigrosso
Thanks.

Do I have this right: because jpeg is an 8-bit format, the image automatically retains the grays, while png doesn't have to be 8-bit, and IM will keep the depth the same as the input file unless otherwise instructed?

PS Is there a formal way to suggest changes to the Usage docs?

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T10:58:45-07:00
by fmw42
Can you post a link to your PGM 1-bit image, so we can examine it and test with it?

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T11:44:19-07:00
by muccigrosso
fmw42 wrote: 2018-02-17T10:58:45-07:00 Can you post a link to your PGM 1-bit image, so we can examine it and test with it?
I did, above.

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T11:56:46-07:00
by fmw42
I believe that the reason for the results you get is that JPG is a lossy compressed format and does not support a true binary format. Due to the block-wise compression, it changes your values from two values to many grayscale values. Thus the JPG result will be 8-bit grayscale. Whereas the PNG compression is not lossy and maintains your two colors. So the result will be 8/1-bit (bilevel), same as the input PGM.

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T12:43:58-07:00
by muccigrosso
fmw42 wrote: 2018-02-17T11:56:46-07:00 I believe that the reason for the results you get is that JPG is a lossy compressed format and does not support a true binary format. Due to the block-wise compression, it changes your values from two values to many grayscale values. Thus the JPG result will be 8-bit grayscale. Whereas the PNG compression is not lossy and maintains your two colors. So the result will be 8/1-bit (bilevel), same as the input PGM.
The jpeg may be lossy, but it's much closer to the original than the 8/1-bit png IM produces by default.

My surprise was learning that IM preserves the depth of the original image even after its pixels have been modified. I thought I had read the opposite somewhere.

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T15:22:04-07:00
by fmw42
IM will try to preserve the bit-depth. But if you do something that adds more colors, it can change the bit depth to support that number of colors, depending upon circumstances. See snibgo's comments below for more details.

I noticed the loss in quality between your original PGM and PNG. That may be due to the fact that PGM is linear gray, if I recall, and PNG assumes non-linear. See https://www.imagemagick.org/script/form ... colorspace

That seems to be true, since this seems to preserve the quality better

Code: Select all

convert test.pgm -grayscale rec709luminance test.png

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T15:52:02-07:00
by snibgo
fmw42 wrote:But if you do something that adds more colors, it will change the bit depth to support that number of colors.
I don't think IM has ever done this, exactly. If the first input image has depth 8, that is retained until the output, or it is changed by "-depth" or "+depth". However, if it isn't one of 8, 16, 32 or 64 it will increase to one of those under certain circumstances, but never to more than the compile-time Q-number, and I'm not sure of the exact circumstances. Quite often, when an input has 1 bit (it is binary black/white), so is the output PNG.

JPEG always has 8 bits/channel/pixel.

TIFF, GIF and PNG can have depth 1.

For example:

Code: Select all

f:\web\im>%IM%convert xc: xc:black +append t.png
f:\web\im>%IM%identify t.png
t.png PNG 2x1 2x1+0+0 8-bit sRGB 2c 258B 0.000u 0:00.031
t.png has 2 colours; it is depth 1.

Code: Select all

f:\web\im>%IM%convert t.png -resize "1000x1^!" -unique-colors info:
t.png PNG 644x1 644x1+0+0 8-bit Gray 0.000u 0:00.000

Resizing it to 1000 pixels makes 644 different colours, but the "depth" has increased to only 8...

Code: Select all

f:\web\im>%IM%convert t.png -resize "1000x1^!" t2.png

f:\web\im>%IM%identify t2.png
t2.png PNG 1000x1 1000x1+0+0 8-bit sRGB 256c 318B 0.000u 0:00.000
... So saving it as PNG has only 256 shades of gray.

Code: Select all

f:\web\im>%IM%convert t.png -resize "1000x1^!" +depth t2.png

f:\web\im>%IM%identify t2.png
t2.png PNG 1000x1 1000x1+0+0 16-bit sRGB 922B 0.000u 0:00.000
f:\web\im>%IM%convert t2.png -unique-colors info:
t2.png PNG 644x1 644x1+0+0 16-bit Gray 0.000u 0:00.000
"+depth" stores as 16-bits (because this IM is Q16) and gives us all the 644 shades of gray.

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T16:03:13-07:00
by fmw42
On Q16, with TIFF, the results are different.

Code: Select all

convert xc: xc:black +append t.tif
identify -verbose says 16/1-bit (2 colors)

but

Code: Select all

convert t.tif -resize 1000x1! t2.tif
identify -verbose 16-bit grayscale with 644 colors.

So I think the resulting bit depth and colors depends upon the output format.

The point is, if you create more colors than your input bit-depth and the output format supports it, you will get a higher bit depth result with more colors.

Re: Convert 2-bit to png after deskew has odd results

Posted: 2018-02-17T22:18:24-07:00
by muccigrosso
fmw42 wrote: 2018-02-17T16:03:13-07:00 The point is, if you create more colors than your input bit-depth and the output format supports it, you will get a higher bit depth result with more colors.
OK, but png certainly supports more than 1 bit of color, yet the result of the deskew operation on my file was a 2-color png, unless I explicitly set a higher depth. (I don't understand what png's reported depth of 8/1 bit means exactly.)

A bunch of results for the colors from identify:

Original pgm: 1-bit Bilevel Gray
info: output after deskew: 1-bit Gray
png output after deskew: 8/1-bit Gray 2c
tiff output after deskew: 1-bit Bilevel Gray
png output after deskew with depth set to 8: 8-bit Gray 256c
tiff output after deskew with depth set to 8: Grayscale Gray

The tiff and png with depth 8 are identical. The png and tiff without 8 bits are not identical. The tiff looks has more black pixels, like the - output, though also not quite identical to it. I don't think I'd have noticed this issue if the png didn't look so different from the original.

Interestingly to me, if I use output and input to/from standard in/out, the depth seems to be ignored and the output png is 8-bit Gray 2c:

convert -deskew 40% -depth 8 test.pgm - | convert - line.png

However using a write to memory yields 8-bit Gray and an identical file to the depth 8 png/tiff:

convert -deskew 40% -depth 8 test.pgm -write mpr:test +delete mpr:test info:

Not setting depth yields 1-bit Gray, as with others.

So, what I see is:

1. Original file depth is preserved in output file, if that output offers the same depth. JPEG therefore gets 8-bit while png or tiff get 1, even though both png and tiff can handle >1 bit.
2. Explicitly setting depth results in output file with that depth and the grays actually used.
3. Writing to - does not preserve the depth even when explicitly set, even though in this case it doesn't calculate which pixels stay black in the same way that the png output does.
4. Writing to memory seems to work like writing to files.

It looks to me like the output file retains the depth setting of the input unless otherwise instructed or unless it can't (like jpeg). Setting depth keeps the new colors resulting (in this case) from the deskew. What I don't get is why using standard in/out seems to ignore the depth.
fmw42 wrote:I noticed the loss in quality between your original PGM and PNG. That may be due to the fact that PGM is linear gray, if I recall, and PNG assumes non-linear.
This doesn't happen without deskew, so a simple convert to png creates an identical image.