sharp icon indicating copy to clipboard operation
sharp copied to clipboard

Enhancement: support floating-point raw pixel output for LAB/LCH

Open btd opened this issue 8 years ago • 4 comments

Hi, there.

I am trying to get Lab colors from image using such code:

sharp(buffer, { raw: opts })
      .toColorspace('lab')
      .raw()
      .toBuffer((err, data, info) => {
        if (err) {
          return reject(err);
        }

        resolve(data);
      });
  });

And i am comparing what i get with what i am expecting for example (using image created in Paint 5*5 px):

Color at pixel 15
Sharp LAB: 63 0 40 255
RGBA: 34 177 76 255
Manual LAB: 63.59512302182216 -57.62819968304833 40.96944518661568

So with this result comming question: How to use Lab colorspace produced by sharp? As a result of toBuffer is a Buffer so it cuts floating data and negative numbers, but lab coordinates could be negative (a and b). Maybe there is way to produce Float32Array or something like this? Another question, why result of Lab conversion 4 channels (iirc LAB does not use alpha)?

Thank you for answers.

btd avatar Jan 14 '17 20:01 btd

LAB values should be signed integer values and the readInt8 function will do the bit-shifting for you. From memory, L values are 0 to 100, AB values are -127 to 127. The alpha channel remains 0 to 255 unsigned.

Sharp LAB: 63 0 40 255 Manual LAB: 63.59512302182216 -57.62819968304833 40.96944518661568

How was the A value converted? I'd expect this to be -57 as signed, 199 as unsigned, so this could be a bug.

lovell avatar Jan 15 '17 15:01 lovell

Hm, in some reason i thought i posted my comment.

Anyway. To ge Lab results i used code above and just printed with console.log (it is line with Sharp LAB). As an image i have used this image: _ To get Manual LAB results i used formulas from wikipedia. There is my implementation in gist. Need to call function RGBtoCIELAB({ r: ..., g: ..., b: ... }). I think also your A and B value range should be scaled. If i got math right A should be around -200 to 200 and B from -500 to 500. But in this case we loose precision too match, am i right there?

btd avatar Jan 15 '17 18:01 btd

I agree that when the expected output is raw LAB pixel data via .toColorspace('lab').raw() (and possibly some other colourspaces too, e.g. LCH), the output should be a Buffer containing 32-bit floating point values. I'll have to take a deeper look to see how this might work.

lovell avatar Jan 16 '17 11:01 lovell

Thank you.

btd avatar Jan 16 '17 12:01 btd