Вопрос по java – Нужен более быстрый способ получить значение RGB для каждого пикселя буферизованного изображения

7

Какой самый быстрый способ получить значение RGB каждого пикселяBufferedImage?

Прямо сейчас я получаю значения RGB, используя дваfor циклы, как показано в приведенном ниже коде, но получение этих значений заняло слишком много времени, поскольку вложенный цикл выполняется для моего изображения в общей сложности 479999 раз. Если бы я использовал 16-битное изображение, это число было бы еще выше!

Мне нужен более быстрый способ получить значения пикселей.

Вот код, с которым я сейчас пытаюсь работать:

BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg"));

int countloop=0;  

for (int x = 0; x <bi.getWidth(); x++) {
    for (int y = 0; y < bi.getHeight(); y++) {
        Color c = new Color(bi.getRGB(x, y));
        System.out.println("red=="+c.getRed()+" green=="+c.getGreen()+"    blue=="+c.getBlue()+"  countloop="+countloop++);                                                                                                                                                  
    }
}
Выход замедляет весь цикл. Попробуйте это без. Matthias Bruns
Посмотри здесьstackoverflow.com/questions/4348613/… dash1e
Это может пойти намного быстрее без печати Romain Hippeau
ВынимаяSystem.out.println() звонки сделают это значительно быстрее. Вы могли бы определитьc вне цикла, и даже избегать созданияColor если вам нужно, но, вероятно, в этом нет необходимости. beerbajay
it can even rise when i will use 16 bit image - Почему количество итераций зависит от количества бит на пиксель? И каков вариант использования для этого? Обратите внимание, что созданиеColor объекты, а также печать на консоль занимает некоторое время. Если вы хотите получить доступ ко всем 479999 пикселям, вы не можете избавиться от цикла (вы можете объединить их в один, но это не должно иметь большого значения). Thomas

Ваш Ответ

5   ответов
2

BufferedImage.getRGB (int, int, int, int, int [], int, int)?

Что-то вроде:

int[] rgb = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(), new int[bi.getWidth() * bi.getHeight(), bi.getWidth()])

Не пытался, поэтому не уверен, что это быстрее.

edit Посмотрев @ код, это, вероятно, не так, но стоит попробовать.

2

аким образом вы избежите промахов кэша.

Error: User Rate Limit Exceeded
12

может ли это помочь, и я еще не проверял это, но вы можете получить значения rgb следующим образом:

BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg"));
int[] pixel;

for (int y = 0; y < bi.getHeight(); y++) {
    for (int x = 0; x < bi.getWidth(); x++) {
        pixel = bi.getRaster().getPixel(x, y, new int[3]);
        System.out.println(pixel[0] + " - " + pixel[1] + " - " + pixel[2] + " - " + (bi.getWidth() * y + x));
    }
}

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

5

By changing from a bunch of in individual getRGB's to one big getRGB to copy the entire image into an array, the execution time dropped by an order of magnitude from 33,000 milliseconds to 3,200 milliseconds, while the time create the array was only 31 milliseconds.

No doubt about it, one big read into an array and direct indexing of the array is much faster than many individual reads.

Разница в производительности связана с использованием оператора точки останова в конце класса. В то время как точка останова была вне цикла, каждая строка кода в классе, по-видимому, проверяется на точку останова. Переход на индивидуальные бонусы НЕ улучшает скорость.

Поскольку код по-прежнему правильный, оставшаяся часть ответа все еще может быть полезной.

Старое прочитанное заявление

colorRed=new Color(bi.getRGB(x,y)).getRed();

Прочитайте инструкцию, чтобы скопировать битовое изображение в массив

int[] rgbData = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(), 
                null, 0,bi.getWidth());        

GetRGB в массиве помещает все 3 значения цвета в один элемент массива, поэтому отдельные цвета должны быть извлечены вращением, а также "и". Координата y должна быть умножена на ширину изображения.

Код для чтения отдельных цветов из массива

colorRed=(rgbData[(y*bi.getWidth())+x] >> 16) & 0xFF; 

colorGreen=(rgbData[(y*bi.getWidth())+x] >> 8) & 0xFF; 

colorBlue=(rgbData[(y*bi.getWidth())+x]) & 0xFF; 
0
,

https://alvinalexander.com/blog/post/java/getting-rgb-values-for-each-pixel-in-image-using-java-bufferedi

BufferedImage bi = ImageIO.read(new File("C:\\images\\Sunset.jpg"));

for (int x = 0; x < bi.getWidth(); x++) {
    for (int y = 0; y < bi.getHeight(); y++) {
        int pixel = bi.getRGB(x, y);
        int red = (pixel >> 16) & 0xff;
        int green = (pixel >> 8) & 0xff;
        int blue = (pixel) & 0xff;
        System.out.println("red: " + red + ", green: " + green + ", blue: " + blue);                                                                                                                                                  
    }
}
Error: User Rate Limit Exceeded

Похожие вопросы