将 HTML 画布裁剪为其可见像素(内容)的宽度/高度?

问题描述 投票:0回答:3

可以对 HTML

canvas
元素进行内部裁剪以适应其内容吗?

例如,如果我有一个 500x500 像素的画布,其中的随机位置只有一个 10x10 像素的正方形,是否有一个函数可以通过扫描可见像素和裁剪将整个画布裁剪为 10x10?


编辑:这被标记为Javascript方法检测不透明的PNG区域的重复,但事实并非如此。该问题详细介绍了如何找到画布中不透明内容的边界,但不是如何裁剪它。我的问题的第一个词是“裁剪”,所以这就是我想关注的重点。

javascript css html canvas
3个回答
14
投票

更好的修剪功能。

虽然给定的答案有效,但它包含一个潜在的危险缺陷,创建一个新的画布而不是裁剪现有的画布,并且(链接区域搜索)效率有些低。

如果您有对画布的其他引用,创建第二个画布可能会出现问题,这很常见,因为通常有两个对画布的引用,例如

canvas
ctx.canvas
。关闭可能会使删除引用变得困难,并且如果关闭结束于某个事件,您可能永远无法删除引用。

缺陷是画布不包含像素。允许将画布设置为零大小(

canvas.width = 0; canvas.height = 0;
不会抛出错误),但某些函数不能接受零作为参数,并且会抛出错误(例如,
ctx.getImageData(0,0,ctx.canvas.width,ctx.canvas.height);
是常见做法,但如果画布没有尺寸)。由于这与调整大小没有直接关系,因此可以忽略这种潜在的崩溃并进入生产代码。

链接搜索会检查每次搜索的所有像素,当找到边缘时包含一个简单的

break
将改善搜索,平均而言仍然有更快的搜索。同时向两个方向搜索,先上下后左右,这样会减少迭代次数。您可以通过逐步执行索引来提高性能,而不是为每个像素测试计算每个像素的地址。例如
data[idx++]
data[x + y * w]

快得多

更强大的解决方案。

以下函数将使用两遍搜索从画布上裁剪透明边缘,同时考虑第一遍的结果以减少第二遍的搜索区域。

如果没有像素,它不会裁剪画布,但会返回

false
,以便可以采取行动。如果画布包含像素,它将返回
true

无需更改对画布的任何引用,因为它已就地裁剪。

// ctx is the 2d context of the canvas to be trimmed
// This function will return false if the canvas contains no or no non transparent pixels.
// Returns true if the canvas contains non transparent pixels
function trimCanvas(ctx) { // removes transparent edges
    var x, y, w, h, top, left, right, bottom, data, idx1, idx2, found, imgData;
    w = ctx.canvas.width;
    h = ctx.canvas.height;
    if (!w && !h) { return false } 
    imgData = ctx.getImageData(0, 0, w, h);
    data = new Uint32Array(imgData.data.buffer);
    idx1 = 0;
    idx2 = w * h - 1;
    found = false; 
    // search from top and bottom to find first rows containing a non transparent pixel.
    for (y = 0; y < h && !found; y += 1) {
        for (x = 0; x < w; x += 1) {
            if (data[idx1++] && !top) {  
                top = y + 1;
                if (bottom) { // top and bottom found then stop the search
                    found = true; 
                    break; 
                }
            }
            if (data[idx2--] && !bottom) { 
                bottom = h - y - 1; 
                if (top) { // top and bottom found then stop the search
                    found = true; 
                    break;
                }
            }
        }
        if (y > h - y && !top && !bottom) { return false } // image is completely blank so do nothing
    }
    top -= 1; // correct top 
    found = false;
    // search from left and right to find first column containing a non transparent pixel.
    for (x = 0; x < w && !found; x += 1) {
        idx1 = top * w + x;
        idx2 = top * w + (w - x - 1);
        for (y = top; y <= bottom; y += 1) {
            if (data[idx1] && !left) {  
                left = x + 1;
                if (right) { // if left and right found then stop the search
                    found = true; 
                    break;
                }
            }
            if (data[idx2] && !right) { 
                right = w - x - 1; 
                if (left) { // if left and right found then stop the search
                    found = true; 
                    break;
                }
            }
            idx1 += w;
            idx2 += w;
        }
    }
    left -= 1; // correct left
    if(w === right - left + 1 && h === bottom - top + 1) { return true } // no need to crop if no change in size
    w = right - left + 1;
    h = bottom - top + 1;
    ctx.canvas.width = w;
    ctx.canvas.height = h;
    ctx.putImageData(imgData, -left, -top);
    return true;            
}

2
投票

HTML canvas 元素可以在内部裁剪以适合其内容吗?

是的,使用此方法(或类似的方法)将为您提供所需的坐标。背景不必是透明的,但为了任何实际用途而必须是统一的(修改代码以适合背景)。

获取坐标后,只需使用

drawImage()
即可渲染该区域:

示例(由于问题中没有提供代码,请根据需要采用):

// obtain region here (from linked method)
var region = {
  x: x1, 
  y: y1, 
  width: x2-x1, 
  height: y2-y1
};

var croppedCanvas = document.createElement("canvas");
croppedCanvas.width = region.width;
croppedCanvas.height = region.height;

var cCtx = croppedCanvas.getContext("2d");
cCtx.drawImage(sourceCanvas, region.x, region.y, region.width, region.height, 
                             0, 0, region.width, region.height);

现在

croppedCanvas
仅包含原始画布的裁剪部分。


0
投票

简单可读版本

两次搜索似乎几乎没有必要,至少在 2024 年是这样。这是我对一个更简单、更易读的版本的看法。

示例图片

使用以下具有透明填充的 320x320 像素图像:

Example image with transparent padding

来源:我自己(随意用于任何目的)

示例代码

在此示例中,您将看到 beforeafter 之间的差异,每个图像周围都有红色边框,以显示透明图像填充结束的位置。

函数

trimImage
迭代每一行和每列像素以检测绘制像素的外部边界。然后,它将该边界内的像素重新绘制到调整大小的画布上。

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
    />

    <title>Strip transparent padding</title>

    <style>
      img, canvas {
        border: 1px solid red;
        margin: 0 10px;
      }
    </style>
  </head>
  <body>
    <script type="module">
      async function trimImage(image) {
        // Create a canvas
        const canvas = document.createElement('canvas')
        const context = canvas.getContext('2d')
        document.body.appendChild(canvas)

        // Convert the image to a bitmap
        const bitmap = await createImageBitmap(image)
        const { width, height } = bitmap

        // Get pixels
        canvas.width = width
        canvas.height = height
        context.drawImage(bitmap, 0, 0)
        const { data: pixels } = context.getImageData(0, 0, width, height)
        context.clearRect(0, 0, width, height)

        // Find new bounds by ignoring transparent pixels
        const bounds = { top: height, left: width, right: 0, bottom: 0 }

        for (const row of Array(height).keys()) {
          for (const col of Array(width).keys()) {
            if (pixels[row * width * 4 + col * 4 + 3] !== 0) {
              if (row < bounds.top) bounds.top = row
              if (col < bounds.left) bounds.left = col
              if (col > bounds.right) bounds.right = col
              if (row > bounds.bottom) bounds.bottom = row
            }
          }
        }

        const newWidth = bounds.right - bounds.left
        const newHeight = bounds.bottom - bounds.top

        // Draw new image
        canvas.width = newWidth
        canvas.height = newHeight
        context.drawImage(
          bitmap,
          bounds.left,
          bounds.top,
          newWidth,
          newHeight,
          0,
          0,
          newWidth,
          newHeight,
        )
      }

      // Load the image
      const image = new Image()
      // image.src = './images/vector-die-with-transparency.webp'
      image.src = 'data:image/webp;base64,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'
      image.onload = async () => {
        document.body.append('Original:')
        document.body.append(image)
        document.body.append(document.createElement('br'))

        document.body.append('Trimmed:')
        await trimImage(image)
      }
    </script>
  </body>
</html>

注意:我必须在此片段中将图像粘贴为 base64,特别是因为我无法从跨源(堆栈溢出 cdn)加载图像,因为

getImageData()
将错误为
The canvas has been tainted by cross-origin data

在正常情况下,您应该能够使用托管在同一源上的上传的 blob 或导入的图像。如果没有,请务必检查跨源方法。

© www.soinside.com 2019 - 2024. All rights reserved.