non-square pixels in PNG

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
fransk
Posts: 4
Joined: 2017-05-10T09:07:46-07:00
Authentication code: 1151

non-square pixels in PNG

Post by fransk »

Hello,

I have a PNG file that is supposed to have non-square pixels. Is there a way to check if that is true? I can not rely on PNG viewers because they are at liberty to present non-square pixels as square, as per the PNG spec.

I have tried the identify command line tool but it does not seem to show pixel dimensions.

Furthermore, I plan to do image processing with ImageMagick. Does it always take pixel dimensions into account when processing?

I am using ImageMagick 7.0.5.

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

Re: non-square pixels in PNG

Post by snibgo »

I suggest you link to an example image with non-square pixels. You can upload to somewhere like dropbox.com and paste the URL here. We can then experiment.

I don't know what IM does with non-square pixels. I don't think it automatically stretches the image to make them square. It might process the pixels as usual, then either write the correct pHYs chunk to the output PNG, or not write the pHYs chunk which will "forget" that the pixels are not square.
snibgo's IM pages: im.snibgo.com
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: non-square pixels in PNG

Post by snibgo »

A png with non-square pixels is https://bug408622.bmoattachments.org/at ... ?id=293449

"identify -verbose" shows:

Code: Select all

    png:pHYs: x_res=1, y_res=4, units=0
Some experiments show that IM 6.9.5-3 doesn't automatically stretch the image to make them square. I can process the image, and write a PNG that will contain the correct pHYs chunk.
snibgo's IM pages: im.snibgo.com
fransk
Posts: 4
Joined: 2017-05-10T09:07:46-07:00
Authentication code: 1151

Re: non-square pixels in PNG

Post by fransk »

Snibgo, thank you for the thorough answers, and I am glad to know that IM respects pixel dimensions in processing.

I checked the output of "identify -verbose" again, but I do not see a "png:pHYs:" line. Perhaps that's because I run IM on Windows? Anyway, that is a different subject.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: non-square pixels in PNG

Post by snibgo »

With IM 7.0.3-5 on Wndows 8.1...

Code: Select all

magick identify -verbose cdfn2c08.png
... gives this:

Code: Select all

Image: cdfn2c08.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 8x32+0+0
  Resolution: 1x4
  Print size: 8x8
  Units: Undefined
  Type: Palette
  Base type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8/4-bit
  Channel depth:
    Red: 4-bit
    Green: 4-bit
    Blue: 4-bit
  Channel statistics:
    Pixels: 256
    Red:
      min: 0 (0)
      max: 255 (1)
      mean: 186.137 (0.729948)
      standard deviation: 94.6659 (0.371239)
      kurtosis: -0.592259
      skewness: -1.01344
      entropy: 0.658902
    Green:
      min: 0 (0)
      max: 255 (1)
      mean: 132.48 (0.519531)
      standard deviation: 96.9733 (0.380287)
      kurtosis: -1.52256
      skewness: -0.055075
      entropy: 0.867358
    Blue:
      min: 0 (0)
      max: 255 (1)
      mean: 35.0625 (0.1375)
      standard deviation: 73.1892 (0.287017)
      kurtosis: 2.33579
      skewness: 1.94241
      entropy: 0.403166
  Image statistics:
    Overall:
      min: 0 (0)
      max: 255 (1)
      mean: 117.893 (0.462326)
      standard deviation: 88.9234 (0.348719)
      kurtosis: -0.126929
      skewness: 0.246186
      entropy: 0.643142
  Colors: 78
  Histogram:
         1: (  0, 85,255) #0055FF srgb(0,85,255)
         2: (  0,136,255) #0088FF srgb(0,136,255)
         1: (  0,170,187) #00AABB srgb(0,170,187)
         3: (  0,187,187) #00BBBB srgb(0,187,187)
         1: (  0,187,238) #00BBEE srgb(0,187,238)
         1: (  0,187,255) #00BBFF srgb(0,187,255)
         1: (  0,204,170) #00CCAA srgb(0,204,170)
         1: (  0,221,170) #00DDAA srgb(0,221,170)
         1: (  0,221,187) #00DDBB srgb(0,221,187)
         1: (  0,221,238) #00DDEE srgb(0,221,238)
         1: (  0,238,153) #00EE99 srgb(0,238,153)
         1: (  0,238,187) #00EEBB srgb(0,238,187)
         1: (  0,255,  0) #00FF00 lime
         2: (  0,255, 34) #00FF22 srgb(0,255,34)
         1: (  0,255, 51) #00FF33 srgb(0,255,51)
         1: (  0,255, 85) #00FF55 srgb(0,255,85)
         3: (  0,255,102) #00FF66 srgb(0,255,102)
         2: (  0,255,119) #00FF77 srgb(0,255,119)
         1: (  0,255,136) #00FF88 srgb(0,255,136)
         1: (  0,255,153) #00FF99 srgb(0,255,153)
         1: ( 17, 85,255) #1155FF srgb(17,85,255)
         2: ( 17,170,187) #11AABB srgb(17,170,187)
         1: ( 17,255,  0) #11FF00 srgb(17,255,0)
         1: ( 17,255, 34) #11FF22 srgb(17,255,34)
         1: ( 17,255, 68) #11FF44 srgb(17,255,68)
         1: ( 34, 34,255) #2222FF srgb(34,34,255)
         1: ( 34, 51,255) #2233FF srgb(34,51,255)
         4: ( 34,238,102) #22EE66 srgb(34,238,102)
         2: ( 34,255, 34) #22FF22 srgb(34,255,34)
         3: ( 34,255, 68) #22FF44 srgb(34,255,68)
         3: ( 34,255, 85) #22FF55 srgb(34,255,85)
         2: ( 51,255,  0) #33FF00 srgb(51,255,0)
         1: ( 68,255,  0) #44FF00 srgb(68,255,0)
         1: ( 85,  0,255) #5500FF srgb(85,0,255)
         1: ( 85, 34,255) #5522FF srgb(85,34,255)
         1: ( 85,255,  0) #55FF00 srgb(85,255,0)
         1: (119, 34,238) #7722EE srgb(119,34,238)
        10: (119,255,  0) #77FF00 srgb(119,255,0)
         2: (136, 34,204) #8822CC srgb(136,34,204)
         1: (136, 34,221) #8822DD srgb(136,34,221)
         6: (136,238,  0) #88EE00 srgb(136,238,0)
         2: (136,255,  0) #88FF00 srgb(136,255,0)
         1: (153,  0,238) #9900EE srgb(153,0,238)
         1: (153, 34,204) #9922CC srgb(153,34,204)
         4: (153,238,  0) #99EE00 srgb(153,238,0)
         1: (153,255,  0) #99FF00 srgb(153,255,0)
         2: (170,238,  0) #AAEE00 srgb(170,238,0)
         3: (170,255,  0) #AAFF00 srgb(170,255,0)
         2: (187,187,  0) #BBBB00 srgb(187,187,0)
         1: (187,238,  0) #BBEE00 srgb(187,238,0)
         2: (187,255,  0) #BBFF00 srgb(187,255,0)
         1: (204,  0,204) #CC00CC srgb(204,0,204)
         6: (204,187,  0) #CCBB00 srgb(204,187,0)
         1: (204,238,  0) #CCEE00 srgb(204,238,0)
         1: (221,170,  0) #DDAA00 srgb(221,170,0)
         2: (221,187,  0) #DDBB00 srgb(221,187,0)
         2: (221,238,  0) #DDEE00 srgb(221,238,0)
         3: (221,255,  0) #DDFF00 srgb(221,255,0)
         3: (238,  0,153) #EE0099 srgb(238,0,153)
         1: (238,  0,170) #EE00AA srgb(238,0,170)
         1: (238,153,  0) #EE9900 srgb(238,153,0)
         1: (238,170,  0) #EEAA00 srgb(238,170,0)
         2: (238,187,  0) #EEBB00 srgb(238,187,0)
         1: (238,255,  0) #EEFF00 srgb(238,255,0)
        41: (255,  0,  0) #FF0000 red
         7: (255, 17,  0) #FF1100 srgb(255,17,0)
         7: (255, 34,  0) #FF2200 srgb(255,34,0)
         9: (255, 51,  0) #FF3300 srgb(255,51,0)
        13: (255, 68,  0) #FF4400 srgb(255,68,0)
         8: (255, 85,  0) #FF5500 srgb(255,85,0)
         5: (255,102,  0) #FF6600 srgb(255,102,0)
        25: (255,119,  0) #FF7700 srgb(255,119,0)
         3: (255,136,  0) #FF8800 srgb(255,136,0)
         5: (255,153,  0) #FF9900 srgb(255,153,0)
         4: (255,170,  0) #FFAA00 srgb(255,170,0)
         4: (255,187,  0) #FFBB00 srgb(255,187,0)
         6: (255,238,  0) #FFEE00 srgb(255,238,0)
         2: (255,255,  0) #FFFF00 yellow
  Rendering intent: Perceptual
  Gamma: 1
  Chromaticity:
    red primary: (0.64,0.33)
    green primary: (0.3,0.6)
    blue primary: (0.15,0.06)
    white point: (0.3127,0.329)
  Alpha color: grey74
  Background color: white
  Border color: srgb(223,223,223)
  Transparent color: none
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 8x32+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2017-05-10T21:42:03+01:00
    date:modify: 2017-05-10T21:41:32+01:00
    png:gAMA: gamma=1 (See Gamma, above)
    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: 8, 32
    png:pHYs: x_res=1, y_res=4, units=0
    signature: 080144e3ff61f0da7ed7088e41d6ca9ee27bea0d4feff317aee6c97f91d224cd
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 404B
  Number pixels: 256
  User time: 0.000u
  Elapsed time: 0:01.000
  Version: ImageMagick 7.0.3-5 Q16 x64 2016-11-08 http://www.imagemagick.org
A line near the top is:

Code: Select all

  Resolution: 1x4
And near the bottom is:

Code: Select all

    png:pHYs: x_res=1, y_res=4, units=0
We can use this is a script to resize an image, making the pixels square. Here is a crude script (it accurately resizes only in one direction). It also resets the resolution (again, crudely) and removes the pHYs chunk. Windows BAT syntax.

Code: Select all

set SRC=cdfn2c08.png

for /F "usebackq" %%L in (`%IMG7%magick ^
  %SRC% ^
  -format "RX=%%x\nRY=%%y\nXFACT=%%[fx:100*resolution.y/resolution.x]" ^
  info:`) do set %%L

if %FACT%==1 (
  echo Image already has square pixels.
) else (
  echo Adjusting image

  %IMG7%magick %SRC% ^
    -resize %XFACT%x100%% ^
    -density 1x1 ^
    -define png:exclude-chunk=pHYs ^
    out.png
)
snibgo's IM pages: im.snibgo.com
fransk
Posts: 4
Joined: 2017-05-10T09:07:46-07:00
Authentication code: 1151

Re: non-square pixels in PNG

Post by fransk »

That data seems to be really missing in my case. Below are two snippets from the output of

Code: Select all

magick identify -verbose myfile.png
Top lines:

Code: Select all

Image: myfile.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 4x3+0+0
  Units: Undefined
  Type: PaletteAlpha
  Base type: TrueColorAlpha
  Endianess: Undefined
Properties:

Code: Select all

 Properties:
    date:create: 2017-05-10T16:52:10+02:00
    date:modify: 2017-05-10T16:51:56+02:00
    png:IHDR.bit-depth-orig: 8
    png:IHDR.bit_depth: 8
    png:IHDR.color-type-orig: 6
    png:IHDR.color_type: 6 (RGBA)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 4, 3
    png:sRGB: intent=0 (Perceptual Intent)
    signature: b8cb18f554b5d6288a952e9e4b4cfdb826bb572f25c31ee7caa538d2d24aa62e
I have just tested on Linux, the output is the same there: no pixel dimension information. My guess is that the pHYs chunk is simply not present in my file. It does not have to be, according the PNG specification: "If the pHYs chunk is not present, pixels are assumed to be square, and the physical size of each pixel is unspecified".
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: non-square pixels in PNG

Post by snibgo »

Yes, if there is no metadata that describes the pixel aspect ratio, it is assumed to be square.

Try your command on the file I linked to. Does that show resolution and pHYs?
snibgo's IM pages: im.snibgo.com
fransk
Posts: 4
Joined: 2017-05-10T09:07:46-07:00
Authentication code: 1151

Re: non-square pixels in PNG

Post by fransk »

Yes, my IM does show the pixel dimension data of your file. I guess that settles it: if identify -verbose does not show pixel dimensions, they are not specified in the PNG file.
Post Reply