Как обрезать прозрачность изображения, но при необходимости сохранить минимальный размер и положение

У меня есть изображение с прозрачным отступом по краям. У меня также есть границы содержимого изображения (сверху, слева, ширина и высота), но иногда оно выходит за эти границы.

Я пытаюсь обрезать изображение всех прозрачных пикселей, НО, при необходимости, я хочу сохранить минимальные границы.

Например, предположим, что у меня есть 10 изображений размером 1000x1000. На некоторых из них контент позиционируется размером 100х100, а размер контента составляет 100х100. Иногда контент имеет рамку или другой переполненный контент, поэтому контент начинается раньше. На некоторых изображениях границы будут

{top:100, left:100, width: 100, height: 100}

Если была граница в 10 пикселей или другое переполняющее содержимое, границы могли бы быть такими:

{top:90, left: 90, width: 120, height: 120}

Как мне обрезать прозрачные пиксели изображения?

Вот что у меня есть на данный момент:

trimImage(image) {
   var spritePixels = bitmapData;
   var spriteImage = image as HTMLImageElement;
   var data = spritePixels; // Uint8buffer
   var spriteWidth = sprite.width;
   var spriteHeight = sprite.height;
   var firstTopPixel = 0;
   var spritePixelLength = spritePixels.length;
   var newImageData = null;
   var newBounds = {top:0, left:0, width:0, height:0}

   var firstRowFound = false;
   var firstColumnFound = false;
   var firstRowWithContent = 0;
   var lastRowWithContent = 0;
   var firstColumnWithContent = 0;
   var lastColumnWithContent = 0;
   var pixel = -1;
   var row = 0;
   var column = 0;


   for(let i = 0; i < spritePixelLength; i += 4) {
      pixel++;
      const red = spritePixels[i];
      const green = spritePixels[i + 1];
      const blue = spritePixels[i + 2];
      const alpha = spritePixels[i + 3];
      row = Math.floor(pixel / spriteWidth);
      column = pixel - spriteWidth * row;
      //console.info("row: "+ row + " col: " + column);
      
      // ROWS
      // get first top row with a pixel in it
      if (firstRowFound==false && alpha!=0){
         firstRowWithContent = row;
         firstRowFound = true;
         console.info("First non transparent pixel found at row: ");
         console.info("row: "+ row + " col: " + column);
      }
      
      // get last row with a content in it
      if (alpha!=0){
         lastRowWithContent = row;
      }
      
      // COLUMNS
      // get first column with content in it
      if (firstColumnFound==false && alpha!=0) {
         console.info("First non transparent pixel found at column: ");
         console.info("row: "+ row + " col: " + column);
         firstColumnWithContent = column;
         firstColumnFound = true;
      }
      
      // get last column with content in it
      if (alpha!=0){
         lastColumnWithContent = column;
      }
   }

   var bounds = {
      top: firstRowWithContent, 
      bottom: lastRowWithContent, 
      left: firstColumnWithContent,
      right: lastColumnWithContent,
      x: firstColumnWithContent,
      y: firstRowWithContent,
      width: lastColumnWithContent - firstColumnWithContent + 1,
      height: lastRowWithContent - firstRowWithContent + 1
   }

   // bounds bottom and right might need + 1? 
   console.info(bounds);
   // todo: get image at bounds
  
   return bounds;
}

var results = trimImage(image);

должна ли функция автоматически обнаруживать прозрачные части? и сохранить только минимальный прямоугольник видимого содержимого?

IT goldman 25.04.2024 21:46

@ITgoldman да. правильно. Думаю, я понял это. я сейчас тестирую

1.21 gigawatts 26.04.2024 01:01
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пример изображения

Используем следующее изображение размером 320x320 пикселей с прозрачным заполнением:

Источник: я (можно использовать в любых целях)

Пример кода

В этом примере вы увидите разницу между «до» и «после», каждое изображение окружено красной рамкой, чтобы показать, где заканчивается прозрачное поле изображения.

Функция 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.

В обычных обстоятельствах вы сможете использовать загруженный большой двоичный объект или импортированное изображение, размещенное в том же источнике. Если нет, обязательно ознакомьтесь с методом перекрестного происхождения.

Другие вопросы по теме