Reputation: 57
I am writing a Image Processing project. Everything is done except blur effect. The common simple algorithm says :
Below the I implemented to add blur effect
BufferedImage result = new BufferedImage(img.getWidth(),
img.getHeight(), img.getType());
int height = img.getHeight();
int width = img.getWidth();
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
int pixel1 = (x == 0 || y == 0) ? 0 : img.getRGB(x - 1, y - 1);
int pixel2 = (y == 0) ? 0 : img.getRGB(x, y - 1);
int pixel3 = (y == 0 || x >= width-1) ? 0 : img.getRGB(x + 1, y - 1);
int pixel4 = (x == 0) ? 0 :img.getRGB(x - 1, y);
int pixel5 = img.getRGB(x, y);
int pixel6 = (x >= height -1) ? 0 :img.getRGB(x + 1, y);
int pixel7 = (x == 0 || y >= height -1) ? 0 :img.getRGB(x - 1, y + 1);
int pixel8 = (y >= height -1) ? 0 :img.getRGB(x, y + 1);
int pixel9 = (x >= width-1 || y >= height - 1) ? 0 :img.getRGB(x + 1, y + 1);
int newPixel = pixel1 + pixel2 + pixel3 + pixel4 + pixel5
+ pixel6 + pixel7 + pixel8 + pixel9;
newPixel = newPixel/9;
int redAmount = (newPixel >> 16) & 0xff;
int greenAmount = (newPixel >> 8) & 0xff;
int blueAmount = (newPixel >> 0) & 0xff;
newPixel = (redAmount<< 16) | (greenAmount << 8) | blueAmount ;
result.setRGB(x, y, newPixel);
}
I got noisy image as result rather than blurred image. I think I am doing something wrong.
Thanks in advance. Note : Any external API is restricted like Kernal, AffineTransfomation or etc...
Upvotes: 2
Views: 1763
Reputation: 5888
Here is version with just loops:
BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType()) ;
final int H = img.getHeight() - 1 ;
final int W = img.getWidth() - 1 ;
for (int c=0 ; c < img.getRaster().getNumBands() ; c++) // for all the channels/bands
for (int x=1 ; x < W ; x++) // For all the image
for (int y=1; y < H ; y++)
{
int newPixel = 0 ;
for (int i=-1 ; i <= 1 ; i++) // For the neighborhood
for (int j=-1 ; j <= 1 ; j++)
newPixel += img.getRaster().getSample(x+i, y+j, c) ;
newPixel = (int)(newPixel/9.0 + 0.5) ;
result.getRaster().setSample(x, y, c, newPixel) ;
}
Don't use getRGB, it's really slow and you have to deal with the conversions. getSample does everything for you.
Upvotes: 2
Reputation: 57
As I said written algorithms are proved. Just forgot to calculate the average for red, green and blue separately. Here is the answer.
BufferedImage result = new BufferedImage(img.getWidth(),
img.getHeight(), img.getType());
int height = img.getHeight();
int width = img.getWidth();
for (int x = 1; x < width-1; x++)
for (int y = 1; y < height-1; y++) {
int redAmount = 0;
int greenAmount = 0;
int blueAmount = 0;
int pixel1 = img.getRGB(x - 1, y - 1);
redAmount += (pixel1 >> 16) & 0xff;
greenAmount += (pixel1 >> 8) & 0xff;
blueAmount += (pixel1 >> 0) & 0xff;
int pixel2 = img.getRGB(x, y - 1);
redAmount += (pixel2 >> 16) & 0xff;
greenAmount += (pixel2 >> 8) & 0xff;
blueAmount += (pixel2 >> 0) & 0xff;
int pixel3 = img.getRGB(x + 1, y - 1);
redAmount += (pixel3 >> 16) & 0xff;
greenAmount += (pixel3 >> 8) & 0xff;
blueAmount += (pixel3 >> 0) & 0xff;
int pixel4 = img.getRGB(x - 1, y);
redAmount += (pixel4 >> 16) & 0xff;
greenAmount += (pixel4 >> 8) & 0xff;
blueAmount += (pixel4 >> 0) & 0xff;
int pixel5 = img.getRGB(x, y);
redAmount += (pixel5 >> 16) & 0xff;
greenAmount += (pixel5 >> 8) & 0xff;
blueAmount += (pixel5 >> 0) & 0xff;
int pixel6 = img.getRGB(x + 1, y);
redAmount += (pixel6 >> 16) & 0xff;
greenAmount += (pixel6 >> 8) & 0xff;
blueAmount += (pixel6 >> 0) & 0xff;
int pixel7 = img.getRGB(x - 1, y + 1);
redAmount += (pixel7 >> 16) & 0xff;
greenAmount += (pixel7 >> 8) & 0xff;
blueAmount += (pixel7 >> 0) & 0xff;
int pixel8 = img.getRGB(x, y + 1);
redAmount += (pixel8 >> 16) & 0xff;
greenAmount += (pixel8 >> 8) & 0xff;
blueAmount += (pixel8 >> 0) & 0xff;
int pixel9 = img.getRGB(x + 1, y + 1);
redAmount += (pixel9 >> 16) & 0xff;
greenAmount += (pixel9 >> 8) & 0xff;
blueAmount += (pixel9 >> 0) & 0xff;
redAmount /= 9;
greenAmount /= 9;
blueAmount /= 9;
int newPixel = (redAmount << 16) | (greenAmount << 8) | blueAmount;
result.setRGB(x, y, newPixel);
}
Upvotes: 0
Reputation: 563
You can not do calculations with the raw RGB integers like you do. This will certainly cause wrong results. (e.g. integer overflows) You have to take care of the each color component on their own.
Edit Just to give you an example: think about what it would mean to calculate the "average" of two pixels 00FFFF and 0000CC?.
What you actually want as result is something like 007FE5, but calculating with the raw integers will cause the "blue" part to be carried over to the yellow part resulting in 008065.
Upvotes: 1