Thread: Blur and sharpen a bitmap

  1. #16
    Registered User
    Join Date
    Feb 2002
    Posts
    37
    Latest version of my source.

    Code:
    	void filter()
    	{
    		int rsum = 0;
    		int gsum = 0;
    		int bsum = 0;
    		int ksum = 0;
    		Pixel p;
    		bmp = new Bitmap(bitmap.getHeight(), bitmap.getWidth()); // Dynamically createas an empty Bitmap
    		int filter[3][3] = {{0,-1,0}, {-1,5,-1}, {0,-1,0}}; // The sharpen filter
    
    		for (int x = 0; x < bitmap.getHeight(); x++)
    		{
    			for (int y = 0; y < bitmap.getWidth(); y++)
    			{
    				for (int row = -1; row < 1; row++)
    				{
    					for (int col = -1; col < 1; col++)
    					{
    						if ((x + row) >= 0 && (x + row) < bmp->getHeight())
    						{
    							if ((y + col) >= 0 && (y + col) < bmp->getWidth())
    							{
    								p = bitmap.getCopyOfPixel(x, y);
    							
    								rsum += filter[row + 1][col + 1] * p.r;	// Red
    								gsum += filter[row + 1][col + 1] * p.g;	// Green
    								bsum += filter[row + 1][col + 1] * p.b;	// Blue
    								ksum += filter[row + 1][col + 1];
    							}
    						}
    					}
    				}
    				
    				// To avoid devision by zero
    				if (ksum == 0)
    				{
    					p.r = rsum;
    					p.g = gsum;
    					p.b = bsum;
    				}
    				else
    				{
    					p.r = rsum / ksum;
    					p.g = gsum / ksum;
    					p.b = bsum / ksum;
    				}
    		
    				// Resets the value
    				rsum = 0;	
    				gsum = 0;
    				bsum = 0;
    				ksum = 0;
    				bmp->setPixel(x, y, p);  // Inserts the pixel
    			}
            }
    }
    It doesn't matter where I reset the sum values it either goes rubbish or just black. Even tried with different numbers in the matrix filter but still nothing.

  2. #17
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    4 for loops??

    Why?

    Code:
    for (DWORD i=0;i<height;i++)
    {
      for (DWORD j=0;j<width;j++)
     {
        DWORD i1=i+1;
        DWORD j1=j+1;
    
        if (i1>height) i1=0;
        if (j1>width) j1=0;
    
        WORD avgRed=Buffer[i][j].red+Buffer[i][j1].red+Buffer[i1][j].red+Buffer[i1][j1].red;
        WORD avgGreen=Buffer[i][j].green+Buffer[i][j1].green+Buffer[i1][j].green+Buffer[i1][j1].green;
        WORD avgBlue=Buffer[i][j].blue+Buffer[i][j1].blue+Buffer[i1][j].blue+Buffer[i1][j1].blue;
    
        avgRed>>=2;
        avgGreen>>=2;
        avgBlue>>=2;
    
        BlurredBuffer[i][j]=RGB((BYTE)avgRed,(BYTE)avgGreen,(BYTE)avgBlue);
       }
    }
    The way you are doing it your values will quickly resolve to 0.

    I know there are other algorithms for this on google. I searched and found about a billion.

    If you are looking for a image manipulation kernel based on matrices there is an easier way. Extract the color values from your bitmap (which is just a big matrix) into a temp matrix the same size as the filter matrix. Concatenate the matrices, write the resulting matrix back into the color buffer or into a blurred buffer. All your values should be normalized so that any muls or divs in your filters won't overflow the data type. With this method you could easily implement any type of matrix filter you want as long as you know how to concatenate the matrices.
    Last edited by VirtualAce; 03-13-2005 at 10:15 AM.

  3. #18
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Bubba, he's trying to implement a sharpen filter.

    I think it's too early to optimize the code. 4 for-loops can be good in the beginninng and it allows changing the filter easily.

    Mikro your for-loops are wrong:
    Code:
    for (int row = -1; row <= 1; row++)
    {
    for (int col = -1; col <= 1; col++)

    Code:
    p = bitmap.getCopyOfPixel(x + row, y + col);
    You need to compare different pixels each time.

    Besides, you should compare (x+row) to bitmap.getWidth(), not getHeight().

    Change this and try again.
    Last edited by Sang-drax; 03-13-2005 at 11:54 AM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  4. #19
    Registered User
    Join Date
    Feb 2002
    Posts
    37
    Code:
    void filter()
    	{
    		int rsum = 0;
    		int gsum = 0;
    		int bsum = 0;
    		int ksum = 0;
    		Pixel p;
    		bmp = new Bitmap(bitmap.getHeight(), bitmap.getWidth()); // Dynamically createas an empty Bitmap
    		int filter[3][3] = {{0,-1,0}, {-1,5,-1}, {0,-1,0}}; // The sharpen filter
    
    		for (int x = 0; x < bitmap.getHeight(); x++)
    		{
    			for (int y = 0; y < bitmap.getWidth(); y++)
    			{
    				for (int row = -1; row <= 1; row++)
    				{
    					for (int col = -1; col <= 1; col++)
    					{
    						if ((x + row) >= 0 && (x + row) < bmp->getHeight())
    						{
    							if ((y + col) >= 0 && (y + col) < bmp->getWidth())
    							{
    								p = bitmap.getCopyOfPixel(x + row, y + col);
    							
    								rsum += filter[row + 1][col + 1] * p.r;	// Red
    								gsum += filter[row + 1][col + 1] * p.g;	// Green
    								bsum += filter[row + 1][col + 1] * p.b;	// Blue
    								ksum += filter[row + 1][col + 1];
    							}
    						}
    					}
    				}
    				
    				// To avoid devision by zero
    				if (ksum == 0)
    				{
    					p.r = rsum;
    					p.g = gsum;
    					p.b = bsum;
    				}
    				else
    				{
    					p.r = rsum / ksum;
    					p.g = gsum / ksum;
    					p.b = bsum / ksum;
    				}
    		
    				// Resets the value
    				rsum = 0;	
    				gsum = 0;
    				bsum = 0;
    				ksum = 0;
    				bmp->setPixel(x, y, p);  // Inserts the pixel
    			}
            }
    }
    Well now that I have done the small changes the result now is partly correct. If I try switching getWidth() and getHeight() then slightly more than 50% of the image is displayed. So I am leaving these at the same place for the moment.

  5. #20
    Registered User
    Join Date
    Feb 2002
    Posts
    37
    Finally it has been solved

    Code:
    void filter()
    	{
    		int rsum = 0;
    		int gsum = 0;
    		int bsum = 0;
    		int ksum = 0;
    		Pixel p;
    		bmp = new Bitmap(bitmap.getHeight(), bitmap.getWidth()); // Dynamically createas an empty Bitmap
    		int filter[3][3] = {{0,-1,0}, {-1,5,-1}, {0,-1,0}}; // The sharpen filter
    
    		for (int x = 0; x < bitmap.getHeight(); x++)
    		{
    			for (int y = 0; y < bitmap.getWidth(); y++)
    			{
    				for (int row = -1; row <= 1; row++)
    				{
    					for (int col = -1; col <= 1; col++)
    					{
    						if ((x + row) >= 0 && (x + row) < bitmap.getHeight())
    						{
    							if ((y + col) >= 0 && (y + col) < bitmap.getWidth())
    							{
    								p = bitmap.getCopyOfPixel(x + row, y + col);
    							
    								rsum += filter[row + 1][col + 1] * p.r;	// Red
    								gsum += filter[row + 1][col + 1] * p.g;	// Green
    								bsum += filter[row + 1][col + 1] * p.b;	// Blue
    								ksum += filter[row + 1][col + 1];
    							}
    						}
    					}
    				}
    				
    				// To avoid devision by zero
    				if (ksum == 0)
    				{
    					p.r = rsum;
    					p.g = gsum;
    					p.b = bsum;
    				}
    				else
    				{
    					if (rsum / ksum > 255)
    						p.r = 255;
    					else if (rsum / ksum < 0)
    						p.r = 0;
    					else
    						p.r = rsum / ksum;
    
    					if (gsum / ksum > 255)
    						p.g = 255;
    					else if (gsum / ksum < 0)
    						p.g = 0;
    					else
    						p.g = gsum / ksum;
    					if (bsum / ksum > 255)
    						p.b = 255;
    					else if (bsum / ksum < 0)
    						p.b = 0;
    					else
    						p.b = bsum / ksum;
    				}
    		
    				// Resets the value
    				rsum = 0;	
    				gsum = 0;
    				bsum = 0;
    				ksum = 0;
    				bmp->setPixel(x, y, p);  // Inserts the pixel
    			}
            }
    }
    I thank everbody that has helped me with this and when I feel that I am done with this program I will post the full source.

  6. #21
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Mikro
    If I try switching getWidth() and getHeight() then slightly more than 50% of the image is displayed. So I am leaving these at the same place for the moment.
    Yes, your code is correct, but you should know that using x for height and y for width is... against common practice. It got me confused, at least.

    Glad that it's finally working.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

Popular pages Recent additions subscribe to a feed