6

I need to join 2 PNG images, with 16 color palette, keep colors number and order as originals.

Both PNGs use the same 16 color palette.

There is a way to create 4 bit indexed PNG with all colors, in exact order, even unused in each PNG?

Edit to be more clear:

I have 2 pictures. The first is "level-000.png":

level-000.png

It is identified as:

Image: level-000.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 144x144+0+0
  Resolution: 28.35x28.35
  Print size: 5.07937x5.07937
  Units: PixelsPerCentimeter
  Type: Palette
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Pixels: 20736
    Red:
      min: 0 (0)
      max: 184 (0.721569)
      mean: 88.6151 (0.34751)
      standard deviation: 27.9329 (0.109541)
      kurtosis: 1.7675
      skewness: 0.143857
    Green:
      min: 0 (0)
      max: 199 (0.780392)
      mean: 68.8957 (0.270179)
      standard deviation: 22.7411 (0.0891808)
      kurtosis: 18.2722
      skewness: 2.87959
    Blue:
      min: 0 (0)
      max: 111 (0.435294)
      mean: 19.4671 (0.0763416)
      standard deviation: 22.1775 (0.0869706)
      kurtosis: 2.80475
      skewness: 1.17593
  Image statistics:
    Overall:
      min: 0 (0)
      max: 199 (0.780392)
      mean: 58.9926 (0.231344)
      standard deviation: 24.4216 (0.095771)
      kurtosis: 17.5446
      skewness: 0.948025
  Colors: 4
  Histogram:
       390: (  0,  0,  0) #000000 black
     10196: ( 67, 57,  0) #433900 srgb(67,57,0)
      9770: (111, 79, 37) #6F4F25 srgb(111,79,37)
       380: (184,199,111) #B8C76F srgb(184,199,111)
  Colormap entries: 16
  Colormap:
         0: (  0,  0,  0) #000000 black
         1: (255,255,255) #FFFFFF white
         2: (104, 55, 43) #68372B srgb(104,55,43)
         3: (112,164,178) #70A4B2 srgb(112,164,178)
         4: (111, 61,134) #6F3D86 srgb(111,61,134)
         5: ( 88,141, 67) #588D43 srgb(88,141,67)
         6: ( 53, 40,121) #352879 srgb(53,40,121)
         7: (184,199,111) #B8C76F srgb(184,199,111)
         8: (111, 79, 37) #6F4F25 srgb(111,79,37)
         9: ( 67, 57,  0) #433900 srgb(67,57,0)
        10: (154,103, 89) #9A6759 srgb(154,103,89)
        11: ( 68, 68, 68) #444444 srgb(68,68,68)
        12: (108,108,108) #6C6C6C srgb(108,108,108)
        13: (154,210,132) #9AD284 srgb(154,210,132)
        14: (108, 94,181) #6C5EB5 srgb(108,94,181)
        15: (149,149,149) #959595 srgb(149,149,149)
  Rendering intent: Perceptual
  Gamma: 0.454545
  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)
  Background color: black
  Border color: srgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 144x144+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2015-04-10T12:24:18+02:00
    date:modify: 2015-04-09T22:33:29+02:00
    png:bKGD: chunk was found (see Background color, above)
    png:IHDR.bit-depth-orig: 4
    png:IHDR.bit_depth: 4
    png:IHDR.color-type-orig: 3
    png:IHDR.color_type: 3 (Indexed)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 144, 144
    png:pHYs: x_res=2835, y_res=2835, units=1
    png:PLTE.number_colors: 16
    png:sRGB: intent=0 (Perceptual Intent)
    signature: 00d9489d55480d588c3329ab0fa844ed2a67eea06fd4dfa793503a36f9c4b160
  Artifacts:
    filename: level-000.png
    verbose: true
  Tainted: False
  Filesize: 337B
  Number pixels: 20.7K
  Pixels per second: 0B
  User time: 0.000u
  Elapsed time: 0:01.000
  Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-18

The second pic is "scacchiera.png".

scacchiera.png

It is identified as:

Image: scacchiera.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 144x144+0+0
  Resolution: 28.35x28.35
  Print size: 5.07937x5.07937
  Units: PixelsPerCentimeter
  Type: Palette
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Pixels: 20736
    Red:
      min: 67 (0.262745)
      max: 111 (0.435294)
      mean: 89 (0.34902)
      standard deviation: 22 (0.0862745)
      kurtosis: -2
      skewness: -1.18433e-11
    Green:
      min: 57 (0.223529)
      max: 79 (0.309804)
      mean: 68 (0.266667)
      standard deviation: 11 (0.0431373)
      kurtosis: -2
      skewness: 7.03683e-11
    Blue:
      min: 0 (0)
      max: 37 (0.145098)
      mean: 18.5 (0.072549)
      standard deviation: 18.5 (0.072549)
      kurtosis: -2
      skewness: 0
  Image statistics:
    Overall:
      min: 0 (0)
      max: 111 (0.435294)
      mean: 58.5 (0.229412)
      standard deviation: 17.7694 (0.0696837)
      kurtosis: 29.9398
      skewness: -1.66976
  Colors: 2
  Histogram:
     10368: ( 67, 57,  0) #433900 srgb(67,57,0)
     10368: (111, 79, 37) #6F4F25 srgb(111,79,37)
  Colormap entries: 16
  Colormap:
         0: (  0,  0,  0) #000000 black
         1: (255,255,255) #FFFFFF white
         2: (104, 55, 43) #68372B srgb(104,55,43)
         3: (112,164,178) #70A4B2 srgb(112,164,178)
         4: (111, 61,134) #6F3D86 srgb(111,61,134)
         5: ( 88,141, 67) #588D43 srgb(88,141,67)
         6: ( 53, 40,121) #352879 srgb(53,40,121)
         7: (184,199,111) #B8C76F srgb(184,199,111)
         8: (111, 79, 37) #6F4F25 srgb(111,79,37)
         9: ( 67, 57,  0) #433900 srgb(67,57,0)
        10: (154,103, 89) #9A6759 srgb(154,103,89)
        11: ( 68, 68, 68) #444444 srgb(68,68,68)
        12: (108,108,108) #6C6C6C srgb(108,108,108)
        13: (154,210,132) #9AD284 srgb(154,210,132)
        14: (108, 94,181) #6C5EB5 srgb(108,94,181)
        15: (149,149,149) #959595 srgb(149,149,149)
  Rendering intent: Perceptual
  Gamma: 0.454545
  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)
  Background color: white
  Border color: srgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 144x144+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2015-04-10T20:46:55+02:00
    date:modify: 2015-04-10T20:46:55+02:00
    png:IHDR.bit-depth-orig: 4
    png:IHDR.bit_depth: 4
    png:IHDR.color-type-orig: 3
    png:IHDR.color_type: 3 (Indexed)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 144, 144
    png:pHYs: x_res=2835, y_res=2835, units=1
    png:PLTE.number_colors: 16
    png:sRGB: intent=0 (Perceptual Intent)
    signature: 8a0ca53e6e6f8e8fc4b141c7194b399ed1fc32473b174b6240addbb3f98864e5
  Artifacts:
    filename: scacchiera.png
    verbose: true
  Tainted: False
  Filesize: 241B
  Number pixels: 20.7K
  Pixels per second: 0B
  User time: 0.000u
  Elapsed time: 0:01.000
  Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-18

As you can see, both pics have same colors:

  Colormap entries: 16
  Colormap:
         0: (  0,  0,  0) #000000 black
         1: (255,255,255) #FFFFFF white
         2: (104, 55, 43) #68372B srgb(104,55,43)
         3: (112,164,178) #70A4B2 srgb(112,164,178)
         4: (111, 61,134) #6F3D86 srgb(111,61,134)
         5: ( 88,141, 67) #588D43 srgb(88,141,67)
         6: ( 53, 40,121) #352879 srgb(53,40,121)
         7: (184,199,111) #B8C76F srgb(184,199,111)
         8: (111, 79, 37) #6F4F25 srgb(111,79,37)
         9: ( 67, 57,  0) #433900 srgb(67,57,0)
        10: (154,103, 89) #9A6759 srgb(154,103,89)
        11: ( 68, 68, 68) #444444 srgb(68,68,68)
        12: (108,108,108) #6C6C6C srgb(108,108,108)
        13: (154,210,132) #9AD284 srgb(154,210,132)
        14: (108, 94,181) #6C5EB5 srgb(108,94,181)
        15: (149,149,149) #959595 srgb(149,149,149)

If i join them with

convert -page 312x144+0+0 "scacchiera.png" -page +168+0 \
   "level-000.png" -background black -layers flatten "joined.png" 

then "joined.png" picture is:

joined.png

It is identified as:

Image: joined.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 312x144+0+0
  Resolution: 28.35x28.35
  Print size: 11.0053x5.07937
  Units: PixelsPerCentimeter
  Type: Palette
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Pixels: 44928
    Red:
      min: 0 (0)
      max: 184 (0.721569)
      mean: 81.9762 (0.321475)
      standard deviation: 33.8163 (0.132613)
      kurtosis: 0.917842
      skewness: -0.743586
    Green:
      min: 0 (0)
      max: 199 (0.780392)
      mean: 63.1826 (0.247775)
      standard deviation: 25.0478 (0.0982265)
      kurtosis: 7.85041
      skewness: 0.0804364
    Blue:
      min: 0 (0)
      max: 111 (0.435294)
      mean: 17.5233 (0.0687188)
      standard deviation: 20.2675 (0.0794802)
      kurtosis: 1.51309
      skewness: 0.876441
  Image statistics:
    Overall:
      min: 0 (0)
      max: 199 (0.780392)
      mean: 54.2274 (0.212656)
      standard deviation: 26.9673 (0.105754)
      kurtosis: 7.87712
      skewness: 0.327418
  Colors: 4
  Histogram:
      3846: (  0,  0,  0) #000000 black
     20564: ( 67, 57,  0) #433900 srgb(67,57,0)
     20138: (111, 79, 37) #6F4F25 srgb(111,79,37)
       380: (184,199,111) #B8C76F srgb(184,199,111)
  Colormap entries: 4
  Colormap:
         0: ( 67, 57,  0) #433900 srgb(67,57,0)
         1: (111, 79, 37) #6F4F25 srgb(111,79,37)
         2: (  0,  0,  0) #000000 black
         3: (184,199,111) #B8C76F srgb(184,199,111)
  Rendering intent: Perceptual
  Gamma: 0.45455
  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)
  Background color: black
  Border color: srgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 312x144+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2015-04-12T15:13:11+02:00
    date:modify: 2015-04-12T15:13:11+02:00
    png:bKGD: chunk was found (see Background color, above)
    png:cHRM: chunk was found (see Chromaticity, above)
    png:gAMA: gamma=0.45454544 (See Gamma, above)
    png:IHDR.bit-depth-orig: 2
    png:IHDR.bit_depth: 2
    png:IHDR.color-type-orig: 3
    png:IHDR.color_type: 3 (Indexed)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 312, 144
    png:pHYs: x_res=2835, y_res=2835, units=1
    png:PLTE.number_colors: 4
    png:sRGB: intent=0 (Perceptual Intent)
    png:text: 2 tEXt/zTXt/iTXt chunks were found
    signature: 2049a10c0a2a73f864125d0ba93ccfc604a750667e3ba1d0fe8fe3be38a1cbea
  Artifacts:
    filename: joined.png
    verbose: true
  Tainted: False
  Filesize: 487B
  Number pixels: 44.9K
  Pixels per second: 4.493MB
  User time: 0.000u
  Elapsed time: 0:01.009
  Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-18

and you can see that palette is totally different from the initial one.

Images are here:

The question is: is there a way to have ALWAYS this palette:

  Colormap entries: 16
  Colormap:
         0: (  0,  0,  0) #000000 black
         1: (255,255,255) #FFFFFF white
         2: (104, 55, 43) #68372B srgb(104,55,43)
         3: (112,164,178) #70A4B2 srgb(112,164,178)
         4: (111, 61,134) #6F3D86 srgb(111,61,134)
         5: ( 88,141, 67) #588D43 srgb(88,141,67)
         6: ( 53, 40,121) #352879 srgb(53,40,121)
         7: (184,199,111) #B8C76F srgb(184,199,111)
         8: (111, 79, 37) #6F4F25 srgb(111,79,37)
         9: ( 67, 57,  0) #433900 srgb(67,57,0)
        10: (154,103, 89) #9A6759 srgb(154,103,89)
        11: ( 68, 68, 68) #444444 srgb(68,68,68)
        12: (108,108,108) #6C6C6C srgb(108,108,108)
        13: (154,210,132) #9AD284 srgb(154,210,132)
        14: (108, 94,181) #6C5EB5 srgb(108,94,181)
        15: (149,149,149) #959595 srgb(149,149,149)

exactly with these 16 colors and in this order for each resluting PNG?

Kurt Pfeifle
  • 86,724
  • 23
  • 248
  • 345
  • I am intrigued as to *why* you actually want to do this - there may be another solution if we knew the reason. – Mark Setchell Apr 13 '15 at 11:37
  • 1
    I need these colors because the images are to be used in an 8 bit computer, with this fixed palette, in this precise order. Having all the data in the correct order, makes things easier ... (...if it is necessary to add other graphics, etc ...) – Flavio Pasqualin Apr 13 '15 at 19:01

2 Answers2

2

I have worked on this some more, and believe I can achieve what you want... basically, I allow ImageMagick to do the repaging and joining of the images exactly as you had it, but then I get ImageMagick to output a NetPBM file in Portable Any Map PNM format. I then encode the PNM format file into a PNG using a Perl encoder I wrote to match your very specific needs as regards the palette. So, for every truecolour 24-bit RGB pixel I read in from the PNM file, I compute which palette entry it is nearest to by doing the sum of the square errors, and then outputting a single palette index.

NetPBM is described here.

The PNM format is really simple to parse and that's why I chose it. It is described here.

So, your original command would be almost identical, except a PNM file is output on stdout and read into the Perl script pnmtopng which then makes the PNG file you wanted:

convert -page 312x144+0+0 scacchiera.png -page +168+0 \
   level-000.png -background black -layers flatten pnm:- |  ./pnmtopng > out.png

The Perl script is here:

#!/usr/bin/perl
use strict;
use warnings;
use Digest::CRC qw(crc32);
use IO::Compress::Deflate qw(deflate $DeflateError) ;

# Our beloved fixed palette
my @palette=(
      [0,0,0],
      [255,255,255],
      [104,55,43],
      [112,164,178],
      [111,61,134],
      [88,141,67],
      [53,40,121],
      [184,199,111],
      [111,79,37],
      [67,57,0],
      [154,103,89],
      [68,68,68],
      [108,108,108],
      [154,210,132],
      [108,94,181],
      [149,149,149]
   );

################################################################################
# Take chunk of PNG data as parameter, calculate its length & CRC, and output it
################################################################################
sub PNGoutputChunk()
{
   my $len=length($_[0])-4;
   my $crc = Digest::CRC->new(type=>"crc32");
   $crc->add($_[0]);
   print pack('N',$len),$_[0],pack('N',$crc->digest);
}

################################################################################
# Main
################################################################################

   # Read P6 PNM file from STDIN
   my $line = <STDIN>;
   chomp($line);
   if ($line ne "P6"){die "Expected P6 format PNM file"}

   # Read width and height from STDIN
   $line = <STDIN>;
   my ($width,$height) = ($line =~ /(\d+)\s+(\d+)/); 
   print STDERR "DEBUG: width=$width, height=$height\n";

   # Read MAX PNM value and ignore
   $line = <STDIN>;

   # Read entire remainder of PNM file
   my $expectedsize=$width * $height * 3;
   my $PNMdata;
   my $bytesRead = read(STDIN,$PNMdata,$expectedsize);
   if($bytesRead != $expectedsize){die "Unable to read PNM data"}

   # Output PNG header chunk
   printf "\x89PNG\x0d\x0a\x1a\x0a";

   my $bitdepth=8;
   my $colortype=3;
   my $compressiontype=0;
   my $filtertype=0;
   my $interlacetype=0;

   # Output PNG IHDR chunk
   my $IHDR='IHDR';
   $IHDR .= pack 'N',$width;
   $IHDR .= pack 'N',$height;
   $IHDR .= pack 'c',$bitdepth;
   $IHDR .= pack 'c',$colortype;
   $IHDR .= pack 'c',$compressiontype;
   $IHDR .= pack 'c',$filtertype;
   $IHDR .= pack 'c',$interlacetype;
   &PNGoutputChunk($IHDR);

   # Output PNG PLTE (palette)
   my $PLTE='PLTE';
   for(my $i=0;$i<scalar @palette;$i++){
      $PLTE .= sprintf('%c',$palette[$i][0]); # Red
      $PLTE .= sprintf('%c',$palette[$i][1]); # Green
      $PLTE .= sprintf('%c',$palette[$i][2]); # Blue
   }
   &PNGoutputChunk($PLTE);

   # Output PNG IDAT chunk
   # RFC-1950 zlib compression
   my $raw;
   # Go through PNM data, and for each RGB pixel, find nearest palette entry
   my @PNMvalues = unpack("C*",$PNMdata);
   print STDERR "Unpacked ",scalar @PNMvalues," from raw\n";
   for(my $pixel=0;$pixel<(scalar @PNMvalues)/3;$pixel++){

      # Output filter type byte (0) at start of each scanline
      if($pixel%$width==0){$raw .= "\x00";}

      my $r=$PNMvalues[(3*$pixel)];   # Red PNM value
      my $g=$PNMvalues[(3*$pixel)+1]; # Green PNM value
      my $b=$PNMvalues[(3*$pixel)+2]; # Blue PNM value
      my $nearest=0;
      my $distmin=(255*255)+(255*255)+(255*255); # Couldn't get further
      # Go through all palette entries to find nearest to this RGB
      for(my $pe=0;$pe<scalar @palette;$pe++){
         my $pr=$palette[$pe][0];   # Red palette value
         my $pg=$palette[$pe][1]; # Green palette value
         my $pb=$palette[$pe][2]; # Blue palette value
         my $dist = ($pr-$r)*($pr-$r) + ($pg-$g)*($pg-$g) + ($pb-$b)*($pb-$b);
         if($dist<$distmin){
            $distmin=$dist;
            $nearest=$pe;
         }
      }
      $raw .= sprintf "%c",$nearest;
      print STDERR "Pixel: $pixel, r=$r, g=$g, b=$b. Chose palette entry $nearest\n";
   }
   print STDERR "Length of raw: ",length($raw);

   my $deflated;
   my $status = deflate \$raw => \$deflated
        or die "deflate failed: $DeflateError\n";

   my $IDAT="IDAT" . $deflated;
   &PNGoutputChunk($IDAT);

   # Output PNG IEND chunk
   &PNGoutputChunk('IEND');

The result is this:

enter image description here

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Seems don't work on my system, or i'm missed something. - file "pnmtopng.pl" created and +x. - tested with "convert -page 312x144+0+0 scacchiera.png -page +168+0 level-000.png -background black -layers flatten pnm:- | ./pnmtopng.pl out.png" but i get errors like "Use of uninitialized value $pb in subtraction (-) at ./pnmtopng.pl line 111, line 3.". Final colormap looks like "0: ( 0, 0, 0) #000000 black, 1: (255, 0, 0) #FF0000 red, 2: (104, 0, 0) #680000 srgb(104,0,0)". I'm using OpenSuse 13.2. – Flavio Pasqualin Apr 14 '15 at 16:21
  • Oh, I am sorry. Please try again - I don't know what happened there as the script does look corrupted. I have re-pasted it. – Mark Setchell Apr 14 '15 at 16:24
  • You can safely remove all debug printing to STDERR, or run with `2> /dev/null` at end. – Mark Setchell Apr 14 '15 at 16:35
  • Nice! Now works as supposed. If no -native- solution is available, this is surely a working one! Thanks! – Flavio Pasqualin Apr 14 '15 at 16:48
  • Excellent! I was pretty pleased with it since I'd never even looked at the PNG Specification till yesterday :-) – Mark Setchell Apr 14 '15 at 21:13
1

I have tried some more and I can't see a way to do this with ImageMagick. You can extract the unique colours from scacchiera.png like this:

convert scacchiera.png -unique-colors -scale 1000 swatch.png

but there are only 2 colours in there, so that is no use:

enter image description here

You can also extract the colormap and make a CLUT like this:

convert xc:"#000000" xc:"#FFFFFF" xc:"#68372B" xc:"#70A4B2" \
        xc:"#6F3D86" xc:"#588D43" xc:"#352879" xc:"#B8C76F" \
        xc:"#6F4F25" xc:"#433900" xc:"#9A6759" xc:"#444444" \
        xc:"#6C6C6C" xc:"#9AD284" xc:"#6C5EB5" xc:"#959595" +append -scale 500 clut.png

which gives you this

enter image description here

You can then use that CLUT like this, but it doesn't help

convert -page 312x144+0+0 "scacchiera.png" -page +168+0      \
"level-000.png" -background black -layers flatten             \
-remap clut.png "joined.png"  

and you can also use it like this but that doesn't work either

convert -page 312x144+0+0 "scacchiera.png" -page +168+0   \
        "level-000.png" -background black -layers flatten \
        clut.png -clut "joined.png" 

You can also try to tell ImageMagick to preserve the colormap like this, but I'll leave you to guess whether that works :-(

convert -define png:preserve-colormap scacchiera.png ...
convert -define png:preserve-colormap=1 scacchiera.png png00:out.png
convert -define png:preserve-colormap=true scacchiera.png png00:out.png

So, I am stuck too :-)

Original Answer

You don't say how you want to join your images, nor provide any images, nor show what you have tried, so you may not get a good answer. This may be close though...

convert 1.png 2.png -append -remap 1.png result.png
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • For what i can understand, this "issue" is related to the way imagemagick -optimize- palette during -conversions-. It puts only used colors in -some kind of- order... I suppose that i need to "disable" the "optimizations" on palette (quantization/dither/what is it) and maybe -force- my colors... But i can't immagine how to do it (and if this might be the right way...) Just to say: if you try to convert the "clut.png" to -what you want-, the final color order change... – Flavio Pasqualin Apr 12 '15 at 16:29
  • Maybe @GlennRanders-Pehrson will take a look and provide some insights - I believe he wrote the IM PNG encoder... – Mark Setchell Apr 12 '15 at 16:35
  • @MarkSetchell: Glenn also co-authored the PNG spec v1.1 in 1998 :-) – Kurt Pfeifle Apr 16 '15 at 11:29
  • @KurtPfeifle Oh, cool, thank you. I didn't know that - I'll add it to the enormous list of stuff I didn't know :-) – Mark Setchell Apr 16 '15 at 13:05
  • @MarkSetchell: Want more? Glenn is also the author of `libpng` and of `pngcrush` :-) – Kurt Pfeifle Apr 16 '15 at 13:16