Primeiro de tudo, você está desnecessariamente (e incorretamente) convertendo o resultado do float em INT em cada ciclo do loop. Sua red
, green
e blue
deve ser do tipo flutuante e deve ser lançado de volta ao número inteiro somente após a convolução (quando convertido de volta ao 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);
O sangramento das cores em seu resultado é causado porque seus coeficientes em matrix
está errado:
0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.28209479177387814f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f = 1.8452741
A soma dos coeficientes em uma matriz de convolução embaçada deve ser 1,0. Quando você aplica essa matriz a uma imagem, você pode obter cores acima de 255. Quando isso acontece, os canais "sangram" no próximo canal (azul para verde, etc.). Uma imagem completamente verde com esta matriz resultaria em:
green = 255 * 1.8452741 ~= 471 = 0x01D7; rgb = 0xFF01D700;
Que é um verde menos intenso com uma pitada de vermelho.
Você pode consertar isso dividindo os coeficientes por 1.8452741
, mas você quer ter certeza de que:
(int)(255.0f * (sum of coefficients)) = 255
Caso contrário, você precisa adicionar uma verificação que limita o tamanho dos canais a 255 e não os deixe envolver. Por exemplo:
if (red > 255.0f)
red = 255.0f;
Em relação à eficiência/otimização:
Pode ser que a diferença de velocidade possa ser explicada por esse elenco desnecessário e chamando de matemática, mas um candidato mais provável é a maneira como você está acessando a imagem. Não estou familiarizado o suficiente com a BufferEdImage e a Raster para aconselhá -lo sobre a maneira mais eficiente de acessar o buffer de imagem subjacente.