javascriptcanvasimagedata

imageData on paletted png results in nearly duplicate colors


It's as it sounds.

enter image description here

The three brownish colors in the lower left corner above.

enter image description here

I expect up to 60 different colors from a paletted png with a palette that contains 60 colors on an image that claims only 16 colors, which I translated to the desired palette, then made sure the image was paletted.

When I go to fetch the palette back from the canvas things are not as they seem.

I really, really don't want to fight against whatever is going on in order to eliminate these near duplicates.

Is there a no-brainer solution, or is it simply "not a chance", good luck with the math for whatever reasons?

EDIT: Current code attempt is here: https://editor.p5js.org/CodeSoup2022/sketches/sbiKb8rqc

The colors in the userPalette of the sketch are as reported by gimp. There are 26 of them in 0xRRGGBB.

The image file is included with the sketch.


Solution

  • As it turns out, gimp wasn't fudging anything.

    I can't explain why exactly the canvas produces slightly varied color values, but it's at least helpful to know that it does.

    I.E. doing:

    ctx.drawImage ( htmlImgageElement, x, y )
    ctx.getImageData ( 0, 0, width, height )
    

    is half baked in one way or another.

    When I load the image using https://github.com/pngjs/pngjs/:

    fetch ( 'metroid-like.png' )
      .then ( response => response.arrayBuffer () )
      .then ( buffer => {
        new png.PNG ( { filterType: 4 } )
          .parse ( buffer, function ( error, data ) {
            // handle raw data
          } )
      } )
    

    I see the expected 26 color values that gimp reports and each of the apparently blank background tiles gets hashed properly and deduplicated in the resulting tile set.

    For reference, the full code is here:
    https://editor.p5js.org/CodeSoup2022/sketches/sbiKb8rqc