0

I tried to draw this image to canvas. https://res.cloudinary.com/casestry-com/image/upload/casestry-studio/render/14PMT/p1/black/2500x3000/gloss_mask.png In my local I checked that the rgb color at (551, 1439) is (18, 255, 255) But when I get the color after drawing the image to canvas the color is changed to (9, 255, 255) Is there any way to get the same color after drawing to canvas?

Here's the fiddle: https://jsfiddle.net/badu3ze6/5/

async function getImage(url) {
  const imageLoadPromise = new Promise((resolve) => {
    const image = new Image();
    image.crossOrigin = "Anonymous";
    image.src = url;
    image.onload = () => {
      resolve(image);
    };
  });
  return imageLoadPromise;
}
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
async function loadImage() {
    const img = await getImage("https://res.cloudinary.com/casestry-com/image/upload/casestry-studio/render/14PMT/p1/black/2500x3000/gloss_mask.png");
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0);
  const data = ctx.getImageData(551, 1439, 1, 1).data;
  try{
    console.log('read by canvas:', [data[0], data[1], data[2]])
  } catch (e) {
    console.log(e);
  }
}

async function readByImageJs() {
    let image = await IJS.Image.load("https://res.cloudinary.com/casestry-com/image/upload/casestry-studio/render/14PMT/p1/black/2500x3000/gloss_mask.png");
  console.log('read by imagejs:', image.getPixelXY(551, 1439));
}

loadImage()
readByImageJs();
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Wang chao
  • 3
  • 2
  • Does this answer your question? [Can I turn off antialiasing on an HTML element?](https://stackoverflow.com/questions/195262/can-i-turn-off-antialiasing-on-an-html-canvas-element). Look at this answer https://stackoverflow.com/a/67800821/5089567 – Konrad Sep 24 '22 at 23:04
  • No it didn't worked. – Wang chao Sep 24 '22 at 23:58
  • `image.getPixelXY(` is part of a 3rd party image loader. The problem must be in its code. Check their documentation. – Blindman67 Sep 25 '22 at 11:35

1 Answers1

0

The problem is that your image does declare an ICC color profile, but doesn't embed it.
Both Chrome and Firefox will choke on it, apparently trying to convert from something to sRGB while the color profile is actually set to sRGB (IEC61966-2.1). (Note that Safari does return the same values as image-js).

If your image had its color profile embedded, both Firefox and Chrome would have been able to decode it too. If your image was declared as RGB without a color profile, they'd also have been able to handle it correctly.

If you can't modify your image, you can also force the browser to not try to manage the color of the image, through the createImageBitmap() method and its colorSpaceConversion option:

const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
async function loadImage() {
  const resp = await fetch("https://res.cloudinary.com/casestry-com/image/upload/casestry-studio/render/14PMT/p1/black/2500x3000/gloss_mask.png")
  const blob = await resp.blob();
  const img = await createImageBitmap(blob, {
    colorSpaceConversion: "none"
  });
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0);
  const data = ctx.getImageData(551, 1439, 1, 1).data;
  try {
    console.log('read by canvas:', [data[0], data[1], data[2]])
  } catch (e) {
    console.log(e);
  }
}

async function readByImageJs() {
  let image = await IJS.Image.load("https://res.cloudinary.com/casestry-com/image/upload/casestry-studio/render/14PMT/p1/black/2500x3000/gloss_mask.png");
  console.log('read by imagejs:', image.getPixelXY(551, 1439));
}

loadImage()
readByImageJs();
<span id="pixel"></span>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid grey"></canvas>
<script src="https://www.lactame.com/lib/image-js/0.21.2/image.min.js"></script>
Kaiido
  • 123,334
  • 13
  • 219
  • 285