Paper.js `getImageData/putImageData` with alpha channel

huangapple go评论62阅读模式
英文:

Paper.js `getImageData/putImageData` with alpha channel

问题

我正在使用Paper.js画布作为源,以及一个简单的画布作为目标。基本上是通过getImageData复制可见图像的一部分,然后使用putImageData将其粘贴到目标画布中。

粘贴的图像没有 alpha 通道。例如,当复制的区域仅包括对象的一部分,其余部分应为空时。我尝试为两个函数都添加{ colorSpace: 'display-p3' },但我发现颜色空间仍然为srgb,仍然没有 alpha 通道。

是否可以在使用Paper.js的getImageData复制/粘贴图像数据时保留 alpha 通道?

这是复制/粘贴的代码。

const rasterTemp = RasterObject.rasterize() // 这是为了重置所有的变换。

const subRasterTemp = rasterTemp.getSubRaster(new data.$paper.Rectangle({
  point: [0, 0], // 这些以及其他坐标仅用于演示
  size: [100, 100],
}))

const imageData = subRasterTemp.getImageData(new data.$paper.Rectangle({
  point: [0, 0],
  size: [100, 100],
}), { colorSpace: 'display-p3' })

canvasTargetContext.putImageData(imageData, 0, 0)
英文:

I'm using Paper.js canvas as a source and a simple canvas as a target. Basically copying a part of the visible image via getImageData and pasting it into the target canvas with putImageData.

The pasted image does not have the alpha channel. For example when the copied area includes just a part of an object and the rest should be empty. I tried adding { colorSpace: 'display-p3' } for both functions, but I see that the color space stays srgb and still no alpha channel.

Is it possible to copy/paste the image data with getImageData preserving the alpha channel with Paper.js?

Here's the copy/paste code.

const rasterTemp = RasterObject.rasterize() // This to reset all the transformations.

const subRasterTemp = rasterTemp.getSubRaster(new data.$paper.Rectangle({
  point: [0, 0], // These and other coordinates are just for the sake of demonstration
  size: [100, 100],
}))

const imageData = subRasterTemp.getImageData(new data.$paper.Rectangle({
  point: [0, 0],
  size: [100, 100],
}), { colorSpace: 'display-p3' })

canvasTargetContext.putImageData(imageData, 0, 0)

答案1

得分: 1

我无法提供翻译代码部分的服务。如果您有任何其他非代码的内容需要翻译,请随时提问。

英文:

I can't really explain the reason why this works, but a workaround for this can be to first draw the image data on a temporary canvas and then draw this temporary canvas on your target canvas. I got the idea from this thread.

And here's a fiddle demonstrating a possible solution.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Debug Paper.js</title>
  <script src="https://unpkg.com/acorn"></script>
  <script src="https://unpkg.com/paper"></script>
  <style>
    html,
    body {
      margin: 0;
      overflow: hidden;
      height: 100%;
    }

    main {
      display: flex;
      gap: 10px;
      justify-content: center;
      margin-top: 20px;
    }

    canvas {
      border: 1px solid;
    }

    p {
      text-align: center;
    }
  </style>
</head>
<body>

<main>
  <div>
    <canvas id="canvas" resize></canvas>
    <p>paper.js canvas</p>
  </div>
  <div>
    <canvas id="target" resize></canvas>
    <p>target canvas</p>
  </div>
</main>

<script>
  // Setup Paper.js
  paper.setup('canvas');

  // Create a circle.
  const circle = new paper.Path.Circle({
    center: paper.view.center,
    radius: 50,
    fillColor: 'orange',
  });

  // Rasterize the drawing.
  const raster = paper.project.activeLayer.rasterize();
  // Get the image data from this raster.
  const imageData = raster.getImageData();

  // Get the target canvas.
  const targetCanvas = document.getElementById('target');
  const context = targetCanvas.getContext('2d');
  // Draw a black rectangle on it so that we can see the transparency.
  context.fillRect(0, 0, 150, 50);
  putImageDataWithAlpha(targetCanvas, imageData);

  function putImageDataWithAlpha(canvas, imageData) {
    // Create a temporary canvas to draw the image data on it.
    const tmpCanvas = document.createElement('canvas');
    // Make it the same size as the given canvas.
    tmpCanvas.width = canvas.width;
    tmpCanvas.height = canvas.height;
    const tmpContext = tmpCanvas.getContext('2d');
    // Draw the image data on it.
    tmpContext.putImageData(imageData, 0, 0);
    // Then draw this temporary canvas on the given canvas.
    canvas.getContext('2d').drawImage(tmpCanvas, 0, 0);
    // Remove the temporary element.
    tmpCanvas.remove();
  };
</script>
</body>
</html>

答案2

得分: 0

Ok, it's not actually the case. Transparency is being preserved. I just visually got an impression that it wasn't. But when I simply saved the canvas as an image I saw the transparency.

英文:

Ok, it's not actually the case. Transparency is being preserved. I just visually got an impression that it wasn't. But when I simply saved the canvas as an image I saw the transparency.

huangapple
  • 本文由 发表于 2023年4月7日 05:03:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75953762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定