Pixelate areas on an image in C#
When the user releases the mouse, the program calls the PixelateArea method shown in the following code.
// Pixelate the area.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.
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;
}
// Find the average of the colors of hte pixels in a rectangle.See the code for additional details.
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);
}



Comments