像素操作不适用于某些图像

Pixel Manipulation does not work on some images

我正在尝试使用像素处理从图像中仅提取白色文本,但它不适用于某些图像。 适用于 https://prnt.sc/24q29qu but not on https://prnt.sc/24pymne 请查看使用的代码,您可以将代码粘贴到控制台中以查看输出。在 chrome 浏览器上测试过。您可以点击控制台中的输出查看图像输出。

    var imageSource = document.querySelector("body > div.image-constrain.js-image-wrap > div > div > img")

    var width = 2*imageSource.width;
    var height = 2*imageSource.height;

    var img = new Image();
    img.crossOrigin = 'anonymous';
    img.src = imageSource.src;
    var c = document.createElement("canvas")
    c.width = width;
    c.height = height;
    var ctx = c.getContext("2d");
    ctx.drawImage(img, 0, 0);

    var imageData = ctx.getImageData(0, 0, width, height);
    var data = imageData.data;
    console.log(data);
    // Replacing All the pixels except white
    for (let i = 0; i < data.length; i += 4) {
        if(data[i] != 255) {
            data[i] = 0;
        }
        if(data[i+1] != 255) {
            data[i+1] = 0;
        }
        if(data[i+2] != 255) {
            data[i+2] = 0;
        }
        if(data[i+3] != 255) {
            data[i+3] = 0;
        }
    }

    console.log(imageData.data);  
     ctx.putImageData(imageData, 0, 0);


        img.src = c.toDataURL();
        pixelatedImage = c.toDataURL();
        console.log(pixelatedImage);

您的代码不是以白色像素为目标,而是以非 255 的每个红绿蓝和 Alpha 通道为目标,并将这些通道设置为 0

这意味着如果你有一个红色 #FF0000 像素,它将保持不变(红色是 #FF (255) 因此不会被定位,G 和 B 已经 0,Alpha 也是 255,所以没有目标。

your image中,绿色部分的绿色通道是255,所以是非目标的。然而它的红色通道既不是0也不是255,你可以看到绿色确实发生了变化。

(async() => {
  const resp = await fetch("https://i.ibb.co/ZKnmnT6/image.png");
  if (!resp.ok) {
    throw resp.status;
  }
  const blob = await resp.blob();
  const image = await createImageBitmap(blob);
  const canvas = document.createElement("canvas");
  canvas.width = image.width;
  canvas.height = image.height;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(image, 0, 0);
  document.body.append(canvas);
  const [r,g,b,a] = ctx.getImageData(0, 0, 1, 1).data;
  console.log({r,g,b,a});
})().catch(console.error);

要定位白色像素,您需要检查四个 RGBA 通道是否全部 255,而不是一次一个。

(async() => {
  const resp = await fetch("https://i.ibb.co/ZKnmnT6/image.png");
  if (!resp.ok) {
    throw resp.status;
  }
  const blob = await resp.blob();
  const image = await createImageBitmap(blob);
  const canvas = document.createElement("canvas");
  canvas.width = image.width;
  canvas.height = image.height;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(image, 0, 0);
  document.body.append(canvas);
  const img = ctx.getImageData(0, 0, image.width, image.height);
  const imgdata = img.data;
  for (let i = 0; i<imgdata.length; i+=4) {
    if (
      imgdata[i  ] !== 255 ||
      imgdata[i+1] !== 255 ||
      imgdata[i+2] !== 255 ||
      imgdata[i+3] !== 255
    ) {
      imgdata[i  ] =
      imgdata[i+1] =
      imgdata[i+2] =
      imgdata[i+3] = 0;
    }
  }
  ctx.putImageData(img, 0, 0);
})().catch(console.error);

但是您可以通过对 ImageData 的 .data 使用 Uint32Array 视图以更高效的方式执行此操作,将每个完整像素视为单个条目,白色像素将是 0xFFFFFFFF(请注意,如果您想定位其他颜色,现在的顺序是 0xAAGGBBRR)。

(async() => {
  const resp = await fetch("https://i.ibb.co/ZKnmnT6/image.png");
  if (!resp.ok) {
    throw resp.status;
  }
  const blob = await resp.blob();
  const image = await createImageBitmap(blob);
  const canvas = document.createElement("canvas");
  canvas.width = image.width;
  canvas.height = image.height;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(image, 0, 0);
  document.body.append(canvas);
  const img = ctx.getImageData(0, 0, image.width, image.height);
  const imgdata = new Uint32Array(img.data.buffer);
  for (let i = 0; i<imgdata.length; i++) {
    if (imgdata[i] !== 0xFFFFFFFF) {
      imgdata[i] = 0x00000000;
    }
  }
  ctx.putImageData(img, 0, 0);
})().catch(console.error);