Search code examples
javascriptcsshtmlcanvas

Cropping an HTML canvas to the width/height of its visible pixels (content)?


Can an HTML canvas element be internally cropped to fit its content?

For example, if I have a 500x500 pixel canvas with only a 10x10 pixel square at a random location inside it, is there a function which will crop the entire canvas to 10x10 by scanning for visible pixels and cropping?


Edit: this was marked as a duplicate of Javascript Method to detect area of a PNG that is not transparent but it's not. That question details how to find the bounds of non-transparent content in the canvas, but not how to crop it. The first word of my question is "cropping" so that's what I'd like to focus on.


Solution

  • Simple readable version

    A two-pass search seems hardly necessary, at least in 2024. Here's my take at a much simpler and more readable version.

    Example image

    Using the following image of 320x320 pixels with transparent padding:

    Example image with transparent padding

    Source: myself (feel free to use for any purpose)

    Example code

    In this example, you'll see the difference between before and after, each image with a red border around it to show where the transparent image padding ends.

    The function trimImage iterates over every row and column of pixels to detect the outer boundaries of the painted pixels. It then redraws the pixels within that boundary onto a resized canvas.

    <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>

    Note: I had to paste in the image as base64 in this snippet specifically because I couldn't load an image from cross origin (stack overflow cdn) because getImageData() will error as The canvas has been tainted by cross-origin data.

    Under normal circumstances you should be able to use the uploaded blob or imported image that's hosted on the same origin. If not, be sure to check out cross-origin method.