如何并行化图像像素化

本文关键字:像素 图像 并行化 | 更新日期: 2023-09-27 18:10:38

我一直在玩一些图像像素化算法,我看到了这篇文章。

private static Bitmap Pixelate(Bitmap image, Rectangle rectangle, Int32 pixelateSize)
{
    Bitmap pixelated = new System.Drawing.Bitmap(image.Width, image.Height);
    // make an exact copy of the bitmap provided
    using (Graphics graphics = System.Drawing.Graphics.FromImage(pixelated))
        graphics.DrawImage(image, new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
            new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
    // look at every pixel in the rectangle while making sure we're within the image bounds
    for (Int32 xx = rectangle.X; xx < rectangle.X + rectangle.Width && xx < image.Width; xx += pixelateSize)
    {
        for (Int32 yy = rectangle.Y; yy < rectangle.Y + rectangle.Height && yy < image.Height; yy += pixelateSize)
        {
            Int32 offsetX = pixelateSize / 2;
            Int32 offsetY = pixelateSize / 2;
            // make sure that the offset is within the boundry of the image
            while (xx + offsetX >= image.Width) offsetX--;
            while (yy + offsetY >= image.Height) offsetY--;
            // get the pixel color in the center of the soon to be pixelated area
            Color pixel = pixelated.GetPixel(xx + offsetX, yy + offsetY);
            // for each pixel in the pixelate size, set it to the center color
            for (Int32 x = xx; x < xx + pixelateSize && x < image.Width; x++)
                for (Int32 y = yy; y < yy + pixelateSize && y < image.Height; y++)
                    pixelated.SetPixel(x, y, pixel);
        }    
    }
    return pixelated;
}

一切都很好,但是我很难并行化(希望是一个词)代码。我知道你应该用锁位之类的东西,但我真的很难做到。我肯定有办法做到像素块/核心。

并行代码不是我的强项

如何并行化图像像素化

使用这里找到的LockBitmap类,代码变成如下使用LockBits:

private static Bitmap PixelateLockBits(Bitmap image, Rectangle rectangle, int pixelateSize)
{
    using (LockBitmap lockBitmap = new LockBitmap(image))
    {
        var width = image.Width;
        var height = image.Height;
        for (Int32 xx = rectangle.X; xx < rectangle.X + rectangle.Width && xx < image.Width; xx += pixelateSize)
        {
            for (Int32 yy = rectangle.Y; yy < rectangle.Y + rectangle.Height && yy < image.Height; yy += pixelateSize)
            {
                Int32 offsetX = pixelateSize / 2;
                Int32 offsetY = pixelateSize / 2;
                // make sure that the offset is within the boundry of the image
                while (xx + offsetX >= image.Width) offsetX--;
                while (yy + offsetY >= image.Height) offsetY--;
                // get the pixel color in the center of the soon to be pixelated area
                Color pixel = lockBitmap.GetPixel(xx + offsetX, yy + offsetY);
                // for each pixel in the pixelate size, set it to the center color
                for (Int32 x = xx; x < xx + pixelateSize && x < image.Width; x++)
                    for (Int32 y = yy; y < yy + pixelateSize && y < image.Height; y++)
                        lockBitmap.SetPixel(x, y, pixel);
            }
        }
    }
    return image;
}

然后可以将内部的2 fors转换为Parallel。:

Parallel.For(xx, xx + pixelateSize, x =>
{
    if (x < width)
    {
        Parallel.For(yy, yy + pixelateSize, y =>
        {
            if (y < height)
            {
                lockBitmap.SetPixel(x, y, pixel);
            }
        });
    }
});