بادئ ذي بدء ، أنت دون داع (وبشكل خاطئ) تحويل نتيجتك من التعويم إلى 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 لنصائحك حول الطريقة الأكثر فعالية للوصول إلى المخزن المؤقت للصور الأساسية.