# Pixelate image with average cell color

I wrote a function that will pixelate an image using the average color of each 4x4 cell.

The function will "split" the image into 4x4 cells, and find the average color of each pixel in the 4x4 cell, and set the 4x4 cell to the average color.

I'd like some help optimizing my function so it can pixelate an image as fast as possible. In its current state the pixelation process is quite slow.

private static Image PixelateImage(Image image)
{
var bitmap = new Bitmap(image.Width, image.Height);
using (var graphics = Graphics.FromImage(bitmap))
{
graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height),
new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
}

// Loop through the image in 4x4 cells.
for (var yy = 0; yy < image.Height && yy < image.Height; yy += 4)
{
for (var xx = 0; xx < image.Width && xx < image.Width; xx += 4)
{
var cellColors = new List<Color>();

// Store each color from the 4x4 cell into cellColors.
for (var y = yy; y < yy + 4 && y < image.Height; y++)
{
for (var x = xx; x < xx + 4 && x < image.Width; x++)
{
}
}

// Get the average red, green, and blue values.
var averageRed = cellColors.Aggregate(0, (current, color) => current + color.R) / cellColors.Count;
var averageGreen = cellColors.Aggregate(0, (current, color) => current + color.G) / cellColors.Count;
var averageBlue = cellColors.Aggregate(0, (current, color) => current + color.B) / cellColors.Count;

var averageColor = Color.FromArgb(averageRed, averageGreen, averageBlue);

// Go BACK over the 4x4 cell and set each pixel to the average color.
for (var y = yy; y < yy + 4 && y < image.Height; y++)
{
for (var x = xx; x < xx + 4 && x < image.Width; x++)
{
bitmap.SetPixel(x, y, averageColor);
}
}
}
}
return bitmap;
}


• There are a few ways to improve performance. One is to scale the image down to the smaller size, then scale it back up to the original size. Another is to render the picture using a pixel shader that handles the averaging. Yet another is to load the image as a texture, generate a MIP map from the texture, then render from the appropriate level of MIP map. Any of these will normally use the GPU for most of the "grunt" work, improving performance substantially. – Jerry Coffin Sep 1 '16 at 0:59

private Image<Bgr, byte> PixelateImage(Image<Bgr, byte> image)