Ответ 1
Вы делаете много вызовов метода getSamples, и они, в свою очередь, делают звонки и звонки и т.д.
Я часто работаю с фотографиями, и типичный трюк, чтобы получить скорость, - это манипулировать непосредственно базовым int [] (в этом случае ваш BufferedImage должен быть подкреплен int []).
Разница между доступом к int [] и выполнением, скажем, getRGB может быть огромной. Когда я пишу гигантский, я имею в виду на два порядка (попробуйте сделать getRGB на OS X 10.4 против int [x], и вы увидите первичную прибыль).
Также нет вызова три раза getSamples. Я бы просто получил один int, соответствующий вашему ARGB-пикселю, а затем bithift, чтобы получить полосы RGB (вы делаете одну гистограмму для R, G и B-компонента правильно?).
Вы можете получить доступ к массиву пикселей, выполнив что-то вроде этого:
final int[] a = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
Также вы можете делать то, что хотите сделать, с одним циклом, зацикливая на все пиксели.
Вместо:
for ( int x = 0; x < width; x++ ) {
for ( int y = 0; y < height; y++ ) {
....
Вы можете сделать:
for ( int p = 0; p < width*height; p++ ) {
Теперь, если вы хотите получить более страстные оптимизации, не так эффективны, насколько это возможно:
-
Использование разворачивания цикла (итерация более 6 миллионов пикселей является одним из редких случаев, когда это может помочь)
-
инвертировать цикл: for (p = width * height - 1; p >= 0; p -)