Page 1 of 1

-define png:size={size}?

Posted: 2017-01-12T10:45:14-07:00
by clawsoon
I just discovered "-define jpeg:size={size}". It has led to a massive speedup in thumbnailing our very large (~50MB) JPEG files. Yay!

In theory, the same thing should be possible with our very large PNG files, shouldn't it, since PNGs also support progressive loading?

Is this already possible with ImageMagick? If not, is it a feature that could be added?

Thanks!

Re: -define png:size={size}?

Posted: 2017-01-16T22:54:41-07:00
by anthony
No. It is something that can be passed to the JPEG library. The PNG library has no such option available.

But remember it just removes pixel rows and columns from the final result. It is not really a good method of re-sizing an image.

Re: -define png:size={size}?

Posted: 2017-01-19T11:53:47-07:00
by clawsoon
Thanks. I'll check in with the libpng folks to see if it's something they're open to adding. What's the function in the JPEG library that's being used, if you happen to know?

With JPEGs, it produces pretty good results if you follow the advice here:

http://www.imagemagick.org/Usage/formats/#jpg_read

...to set "-define jpeg:size=" to twice the dimensions of the thumbnail you're making in order to avoid aliasing in the final thumbnail.

Re: -define png:size={size}?

Posted: 2017-01-19T16:17:22-07:00
by anthony
LOL... I wrote that advise!!!

Re: -define png:size={size}?

Posted: 2017-01-19T20:02:30-07:00
by glennrp
It would require a small modification to libpng

in libpng/pngpread.c line 683, test for last_pass instead of 6,
and in libpng/pngread.c line 3262, passes=last_pass instead of PNG_INTERLACE_ADAM7_PASSES

then we could use
-define png:last_pass={pass}
where pass=1,3, or 5.

But I doubt that you'd like the resulting images.

Re: -define png:size={size}?

Posted: 2017-01-20T08:05:43-07:00
by clawsoon
I've posted a feature request to the libpng mailing list, here:

https://sourceforge.net/p/png-mng/mailm ... sg35614399

glennrp, would you be interested in posting your patch to that thread, or should I? I'm hesitant to do it, because if there are any follow-up questions I'll have no idea what I'm talking about. :-)
glennrp wrote:But I doubt that you'd like the resulting images.
The quality is pretty good if - as anthony forgot that he advised on the Usage/formats page :-) - you read in at twice the final resolution of the thumbnail. I'm reducing some images by ~40x (19,200x10,800->480x270), so it's very helpful.

Re: -define png:size={size}?

Posted: 2017-01-20T08:19:04-07:00
by clawsoon
I'm looking at the libpng manual, and I'm wondering if that change will only work for interlaced images. With non-interlaced images, would ImageMagick be able to read in only a sample of the rows? I assume that this part about reading in one row at a time suggests it's possible:
If you don't want to read in the whole image at once, you can
use png_read_rows() instead. If there is no interlacing (check
interlace_type == PNG_INTERLACE_NONE), this is simple:

png_read_rows(png_ptr, row_pointers, NULL,
number_of_rows);

where row_pointers is the same as in the png_read_image() call.

If you are doing this just one row at a time, you can do this with
a single row_pointer instead of an array of row_pointers:

png_bytep row_pointer = row;
png_read_row(png_ptr, row_pointer, NULL);
...but I don't know enough about libpng or ImageMagick to know if I'm right.

And my math was obviously wrong: I'm reducing the dimensions by ~40x, but I'm reducing the images by ~1,600x. I don't expect to see a 1,600x speedup :-), but even if I can read in 20x less data and have thumbnail generation that goes 2-4x as fast (and less load on the server), I'll be very happy.

Re: -define png:size={size}?

Posted: 2017-01-20T15:41:29-07:00
by glennrp
The most reduction you can get by skipping interlace passes is 64:1 (only display one dot for each 8x8 block of pixels). But as I said you probably won't like the result. It would be OK for photos, but any fine detail is going to be lost. I'll work up a demo -- but in the meantime, look at Greg Roelofs' book, PNG: The Definitive Guide, Figure 1-4, page 13. The second column of the figure is what libpng gives you by default. Firefox uses an interpolated display, similar to the third column. The book is online at http://www.libpng.org/pub/png/book/chap ... 01.div.2.3

Re: -define png:size={size}?

Posted: 2017-01-20T15:50:26-07:00
by glennrp
clawsoon wrote:
2017-01-20T08:19:04-07:00
I'm looking at the libpng manual, and I'm wondering if that change will only work for interlaced images.
correct.
With non-interlaced images, would ImageMagick be able to read in only a sample of the rows? I assume that this part about reading in one row at a time suggests it's possible:
If you don't want to read in the whole image at once, you can
use png_read_rows() instead. If there is no interlacing (check
interlace_type == PNG_INTERLACE_NONE), this is simple:

png_read_rows(png_ptr, row_pointers, NULL,
number_of_rows);

where row_pointers is the same as in the png_read_image() call.

If you are doing this just one row at a time, you can do this with
a single row_pointer instead of an array of row_pointers:

png_bytep row_pointer = row;
png_read_row(png_ptr, row_pointer, NULL);
Unfortunately, no. A PNG decoder has to read all the rows, whether it reads them in
batches or one at a time.
...but I don't know enough about libpng or ImageMagick to know if I'm right.

And my math was obviously wrong: I'm reducing the dimensions by ~40x, but I'm reducing the images by ~1,600x. I don't expect to see a 1,600x speedup :-), but even if I can read in 20x less data and have thumbnail generation that goes 2-4x as fast (and less load on the server), I'll be very happy.

Re: -define png:size={size}?

Posted: 2017-01-20T15:53:52-07:00
by glennrp
What is the nature of your 50mb PNG files? Are they drawings, aero photos, maps, or what? Are they RGB, RGBA, indexed? All of these would be useful for figuring out how to proceed here.

Re: -define png:size={size}?

Posted: 2017-01-20T16:12:16-07:00
by glennrp
clawsoon wrote:
2017-01-20T08:05:43-07:00
I've posted a feature request to the libpng mailing list, here:

https://sourceforge.net/p/png-mng/mailm ... sg35614399
I didn't see it. Now that you mentioned it here, I hunted for it and found your message in my spam folder. Thanks, gmail.

Glenn

Re: -define png:size={size}?

Posted: 2017-01-23T11:05:11-07:00
by clawsoon
glennrp wrote:
2017-01-20T15:53:52-07:00
What is the nature of your 50mb PNG files? Are they drawings, aero photos, maps, or what? Are they RGB, RGBA, indexed? All of these would be useful for figuring out how to proceed here.
They are exported from Photoshop files (which are themselves large, from 1-2GB), created by artists drawing high-resolution background images that allow panning and zooming for animated children's TV shows. When they make minor revisions and save them out, the newest revision needs to be thumbnailed. Sometimes the exported PNG files are drawn on by directors to show revisions that should be made, and those revision note PNGs also need to be thumbnailed after being modified.

One thing I'm thinking of doing to make sure the thumbnails are available ASAP is setting up directory watchers, though I understand that directory watching can be a bit flaky with Windows file servers.

Here's the output from identify -verbose, if that helps answer some of your questions:
Image: D130/1. LOCATIONS/4-READY FOR LAYOUT/For Nat and Kay/D130_L007_CARNIVALLANE_REV.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 14160x6992+0+0
Resolution: 118.11x118.11
Print size: 119.888x59.1991
Units: PixelsPerCentimeter
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
Red: 8-bit
Green: 8-bit
Blue: 8-bit
Channel statistics:
Pixels: 99006720
Red:
min: 0 (0)
max: 255 (1)
mean: 124.51 (0.488273)
standard deviation: 66.0747 (0.259117)
kurtosis: -0.710447
skewness: 0.137203
entropy: 0.928799
Green:
min: 0 (0)
max: 255 (1)
mean: 156.306 (0.612964)
standard deviation: 66.6374 (0.261323)
kurtosis: -0.746925
skewness: -0.596985
entropy: 0.885491
Blue:
min: 0 (0)
max: 255 (1)
mean: 140.19 (0.549766)
standard deviation: 84.7822 (0.332479)
kurtosis: -1.6854
skewness: -0.0940079
entropy: 0.78357
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 140.335 (0.550334)
standard deviation: 73.0169 (0.286341)
kurtosis: -1.17391
skewness: -0.164318
entropy: 0.865953
Rendering intent: Perceptual
Gamma: 0.454545
Chromaticity:
red primary: (0.63999,0.33001)
green primary: (0.3,0.6)
blue primary: (0.15,0.05999)
white point: (0.31269,0.32899)
Alpha color: grey74
Background color: white
Border color: srgb(223,223,223)
Transparent color: none
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 14160x6992+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
date:create: 2016-09-01T12:07:51+01:00
date:modify: 2016-09-01T12:12:23+01:00
png:cHRM: chunk was found (see Chromaticity, above)
png:iCCP: chunk was found
png:IHDR.bit-depth-orig: 8
png:IHDR.bit_depth: 8
png:IHDR.color-type-orig: 2
png:IHDR.color_type: 2 (Truecolor)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 14160, 6992
png:pHYs: x_res=11811, y_res=11811, units=1
signature: 659c618a4e77a41be317f2fbd791bebba76837181e67e5ac9c59c30795a41cec
Artifacts:
verbose: true
Tainted: False
Filesize: 52.74MB
Number pixels: 99.01M
Pixels per second: 29.79MB
User time: 2.609u
Elapsed time: 0:04.323
Version: ImageMagick 7.0.3-9 Q16 x64 2016-12-05 http://www.imagemagick.org