История изменений
Исправление
Legioner,
(текущая версия)
:
Вот тебе пример алгоритма, который может сработать в твоём случае. Код сильно усложнится, но работать будет очень быстро в сравнение с твоим вариантом.
Во-первых для хранения статистики цветов тебе надо помимо хранения массива в 16 миллионов элементов ещё хранить просто список ненулевых цветов. Т.е. у тебя на картинке например 1000 разных цветов встречается. Это значит, что в массиве rgb у тебя будет 1000 ненулевых элементов, а остальные нулевые. И когда ты его будешь сравнивать с другим массивом, ты 99.9% времени будешь крутить вхолостую. А если ты хранишь конкретный список ненулевых элементов, то тебе надо будет пройтись только по ним. Весь этот функционал разумно вынести в класс. ColorStatistic какой-нибудь.
Во-вторых ты считаешь c_rgb каждый раз заново для каждого участка второй картинки. Это можно сильно оптимизировать. Примерно так: сначала считаешь исходный вариант для x = 0, y = 0 (аналогично rgb, просто считаешь число разных цветов). После этого ты движешься по x вправо до img2.width - img1.width. На каждой итерации ты не пересчитываешь этот c_rgb заново, а просто прибавляешь статистику для столбца шириной в 1 пиксель справа и вычитаешь статистику для столбца шириной в 1 пиксель слева. Таким образом у тебя будет верная статистика, но для её подсчёта ты тратишь не width * height операций, а 2 * height операций. В конце строки сдвигаешься на один пиксель вниз и аналогично прибавляешь статистику для строки высотой в один пиксель, которая снизу и вычитаешь статистику для строки высотой в один пиксель сверху. И потом движешься уже назад, влево. И так «змейкой» обходишь всю картинку img2.
Пока обходишь, на каждой итерации тебе надо сравнивать статистику для первой картинки, которую ты один раз подсчитал и не трогаешь и статистику для части второй картинки, которую ты в данный момент считаешь. Собственно для этого ты итерируешься не 256 * 256 * 256 раз, а только по тем цветам, которые ты до этого запоминал, как ненулевые хотя бы в одной картинке.
Да, что касается BufferedImage. Рекомендую просто сделать массив двумерный конкретно для картинки и перед началом работы «выгрузить» всю картинку в этот простой массив. BufferedImage достаточно тормозной класс, проще и быстрей работать с простым массивом.
Исходная версия
Legioner,
:
Вот тебе пример алгоритма, который может сработать в твоём случае. Код сильно усложнится, но работать будет очень быстро в сравнение с твоим вариантом.
Во-первых для хранения статистики цветов тебе надо помимо хранения массива в 16 миллионов элементов ещё хранить просто список ненулевых цветов. Т.е. у тебя на картинке например 1000 разных цветов встречается. Это значит, что в массиве rgb у тебя будет 1000 ненулевых элементов, а остальные нулевые. И когда ты его будешь сравнивать с другим массивом, ты 99.9% времени будешь крутить вхолостую. А если ты хранишь конкретный список ненулевых элементов, то тебе надо будет пройтись только по ним. Весь этот функционал разумно вынести в класс. ColorStatistic какой-нибудь.
Во-вторых ты считаешь c_rgb каждый раз заново для каждого участка второй картинки. Это можно сильно оптимизировать. Примерно так: сначала считаешь исходный вариант для x = 0, y = 0 (аналогично rgb, просто считаешь число разных цветов). После этого ты движешься по x вправо до img2.width - img1.width. На каждой итерации ты не пересчитываешь этот c_rgb заново, а просто прибавляешь статистику для столбца шириной в 1 пиксель справа и вычитаешь статистику для столбца шириной в 1 пиксель слева. Таким образом у тебя будет верная статистика, но для её подсчёта ты тратишь не width * height операций, а 2 * height операций. В конце строки сдвигаешься на один пиксель вниз и аналогично прибавляешь статистику для строки высотой в один пиксель, которая снизу и вычитаешь статистику для строки высотой в один пиксель сверху. И потом движешься уже назад, влево. И так «змейкой» обходишь всю картинку img2.
Пока обходишь, на каждой итерации тебе надо сравнивать статистику для первой картинки, которую ты один раз подсчитал и не трогаешь и статистику для части второй картинки, которую ты в данный момент считаешь. Собственно для этого ты итерируешься не 256 * 256 * 256 раз, а только по тем цветам, которые ты до этого запоминал, как ненулевые хотя бы в одной картинке.