Прежде всего, вы без необходимости (и ошибочно) преобразуете свой результат из Float в Int в каждом цикле цикла. Ваш red
, green
а также blue
Должен быть типа, и должен быть отменен в целое число только после свертки (при преобразовании обратно в RGB):
float red=0.0f, green = 0.0f, blue = 0.0f
for(int i = x;i<x+3;i++){
for(int j = y;j<y+3;j++){
int color = a.getRGB(i,j);
red += ((color >> 16) & 0xff)*matrix[(i-x)*3+j-y];
green += ((color >> 8) & 0xff)*matrix[(i-x)*3+j-y];
blue += ((color >> 0) & 0xff)*matrix[(i-x)*3+j-y];
}
}
return (a.getRGB(x, y)&0xFF000000) | (((int)red) << 16) | (((int)green) << 8) | ((int)blue);
Кровотечение цветов в вашем результате вызвано потому, что ваши коэффициенты в matrix
не правы:
0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.28209479177387814f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f = 1.8452741
Сумма коэффициентов в размывающейся матрице свертки должна быть 1,0. Когда вы применяете эту матрицу к изображению, вы можете получить цвета более 255. Когда это происходит, каналы «кровоточат» в следующем канале (синий - зеленый и т. Д.). Полностью зеленое изображение с этой матрицей приведет к:
green = 255 * 1.8452741 ~= 471 = 0x01D7; rgb = 0xFF01D700;
Который является менее интенсивным зеленым с оттенком красного.
Вы можете исправить это, разделяя коэффициенты на 1.8452741
, но вы хотите убедиться, что:
(int)(255.0f * (sum of coefficients)) = 255
Если нет, вам нужно добавить чек, который ограничивает размер каналов до 255, и не позволяйте им обернуться. Например:
if (red > 255.0f)
red = 255.0f;
Относительно эффективности/оптимизации:
Может случиться так, что разница в скорости может быть объяснена этим ненужным кастингом и вызовом математики, но более вероятным кандидатом является то, как вы получаете доступ к изображению. Я недостаточно знаком с BufferedImage и Raster, чтобы советовать вам по наиболее эффективному способу получить доступ к базовому буферу изображения.