Вы делаете лот из getSamples вызовов методов, и они в свою очередь выполняют вызовы и вызовы и т. Д.
Я часто работаю с изображениями, и типичный трюк для увеличения скорости заключается в непосредственном манипулировании базовым int [] (в этом случае ваш BufferedImage должен быть поддержан int [] ).
Разница между доступом к int [] и, скажем, getRGB может быть гигантской. Когда я пишу гигантский, я имею в виду целых два порядка (попробуйте сделать getRGB на OS X 10,4 против int [x] , и вы увидите увеличение производительности) .
Кроме того, три раза нет вызова getSamples . Я бы просто получил одно целое число, соответствующее вашему пикселю ARGB, а затем смещение по битам, чтобы получить полосы 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 миллионов пикселей - один из редких случаев, когда это может помочь)
инвертировать цикл: для (p = ширина * высота - 1; p> = 0; p -)