Pixelate areas on an image in C#

The program stores bitmaps holding the original image the user loaded and the modified image that is currently being displayed. The PictureBox's MouseDown, MouseMove, and MouseUp event handlers draw a rubber band box to let the user select an area.
When the user releases the mouse, the program calls the PixelateArea method shown in the following code.
// Pixelate the area.
private Bitmap PixelateArea(Bitmap input_bm, int x, int y, int wid, int hgt)
{
const int cell_wid = 20;
const int cell_hgt = cell_wid;

// Start with the current image.
Bitmap bm = new Bitmap(input_bm);
using (Graphics gr = Graphics.FromImage(bm))
{
// Make x and y multiples of cell_wid/cell_hgt
// from the origin.
int new_x = cell_wid * (int)(x / cell_wid);
int new_y = cell_hgt * (int)(y / cell_hgt);

// Pixelate the selected area.
for (int x1 = new_x; x1 <= x + wid; x1 += cell_wid)
{
for (int y1 = new_y; y1 <= y + hgt; y1 += cell_hgt)
{
// Get the average color in the area.
Color ave_color = AverageRectangle(
input_bm, x1, y1, cell_wid, cell_hgt);

// Fill the area.
using (SolidBrush ave_brush = new SolidBrush(ave_color))
{
gr.FillRectangle(ave_brush, x1, y1, cell_wid, cell_hgt);
}
}
}
}

return bm;
}

PixelateArea creates a copy of the input bitmap. (The program passes the currently displayed image for this parameter so any previous pixelation is still shown.) If you think of the image as being divided into cells of size cell_wid by cell_hgt, the code determines the cell that contains the selected area's upper left corner. The program does this so the blocks in multiple pixelations will line up nicely.

Starting at this cell, the program increases X and Y coordinates by the distances cell_wid and cell_hgt until it has covered the originally selected area. For each cell in the area, the program calls the AverageRectangle method to get the average color value of the pixels in the cell. It then uses FillRectangle to give all of the pixels in that rectangle the average color.

The AverageRectangle method shown in the following code is reasonably straightforward.

// Find the average of the colors of hte pixels in a rectangle.
private Color AverageRectangle(Bitmap input_bm, int x, int y, int wid, int hgt)
{
// Make sure we don't exceed the image's bounds.
if (x < 0) x = 0;
if (x + wid >= input_bm.Width) wid = input_bm.Width - x - 1;
if (wid <= 0) return Color.Black;

if (y < 0) y = 0;
if (y + hgt >= input_bm.Height) hgt = input_bm.Height - y - 1;
if (hgt <= 0) return Color.Black;

// Get the total red, green, and blue values.
Color clr;
int r = 0, g = 0, b = 0;
for (int i = 0; i < hgt; i++)
{
for (int j = 0; j < wid; j++)
{
clr = input_bm.GetPixel(x + j, y + i);
r += clr.R;
g += clr.G;
b += clr.B;
}
}

// Calculate the averages.
r = (int)(r / (wid * hgt));
g = (int)(g / (wid * hgt));
b = (int)(b / (wid * hgt));

return Color.FromArgb(255, r, g, b);
}

See the code for additional details.

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.