Я ищу самый быстрый способ получить данные о пикселях (в форме int[][]
) из файла BufferedImage
. Моя цель - иметь возможность обращаться к пикселям (x, y)
изображения, используя int[x][y]
. Все методы, которые я нашел, этого не делают (большинство из них возвращают int[]
s).
118
getRGB
иsetRGB
напрямую?getRGB
иsetRGB
напрямую.Ответы:
Я просто играл с тем же предметом, это самый быстрый способ получить доступ к пикселям. В настоящее время я знаю два способа сделать это:
getRGB()
метода BufferedImage, как описано в ответе @ tskuzzy.Получая доступ к массиву пикселей напрямую, используя:
Если вы работаете с большими изображениями и производительность является проблемой, первый метод - совершенно не лучший вариант. Этот
getRGB()
метод объединяет значения альфа, красного, зеленого и синего в одно целое, а затем возвращает результат, который в большинстве случаев вы делаете наоборот, чтобы вернуть эти значения.Второй метод будет возвращать значения красного, зеленого и синего цветов непосредственно для каждого пикселя, и если есть альфа-канал, он добавит альфа-значение. Использовать этот метод сложнее с точки зрения расчета индексов, но он намного быстрее, чем первый подход.
В моем приложении я смог сократить время обработки пикселей более чем на 90%, просто переключившись с первого подхода на второй!
Вот сравнение, которое я установил для сравнения двух подходов:
Вы можете угадать результат? ;)
источник
convertTo2DUsingGetRGB
иconvertTo2DWithoutUsingGetRGB
. Первый тест в среднем занимает 16 секунд. Второй тест в среднем занимает 1,5 секунды. Сначала я подумал, что «s» и «ms» - это два разных столбца. @Mota, отличная ссылка.BufferedImage
,type
например,TYPE_INT_RGB
илиTYPE_3BYTE_BGR
и обработать соответствующим образом. Это одна из вещей, которыеgetRGB()
делают за вас, что замедляет работу :-(|=
вместо+=
объединения значений в методе 2?Что-то вроде этого?
источник
BufferedImage
равно сохранил пиксели, используя массив 2D int?Raster
буферу данных, что определенно хорошо, поскольку это приводит к ускорению.Я обнаружил, что ответ Моты дал мне 10-кратное увеличение скорости - так что спасибо Моте.
Я заключил код в удобный класс, который принимает BufferedImage в конструкторе и предоставляет эквивалентный метод getRBG (x, y), который делает его заменой для кода с использованием BufferedImage.getRGB (x, y)
источник
Ответ Mota великолепен, если ваш BufferedImage не был получен из монохромного растрового изображения. Монохромное растровое изображение имеет только 2 возможных значения пикселей (например, 0 = черный и 1 = белый). Когда используется монохромное растровое изображение,
call возвращает необработанные данные Pixel Array таким образом, что каждый байт содержит более одного пикселя.
Поэтому, когда вы используете монохромное растровое изображение для создания объекта BufferedImage, тогда вы хотите использовать следующий алгоритм:
источник
Если полезно, попробуйте следующее:
источник
Вот еще одна реализация FastRGB, найденная здесь :
Что это?
Чтение изображения пиксель за пикселем с помощью метода getRGB в BufferedImage происходит довольно медленно, этот класс - решение этой проблемы.
Идея состоит в том, что вы создаете объект, передавая ему экземпляр BufferedImage, и он считывает все данные сразу и сохраняет их в массиве. Если вы хотите получить пиксели, вы вызываете getRGB
зависимости
Соображения
Хотя FastRGB значительно ускоряет чтение пикселей, это может привести к высокому использованию памяти, так как просто сохраняет копию изображения. Итак, если у вас есть 4 МБ BufferedImage в памяти, после создания экземпляра FastRGB использование памяти станет 8 МБ. Однако вы можете повторно использовать экземпляр BufferedImage после создания FastRGB.
Будьте осторожны, чтобы не попасть в OutOfMemoryException при использовании на таких устройствах, как телефоны Android, где оперативная память является узким местом.
источник
Это сработало для меня:
источник
i
?