如何并行化图像像素化
本文关键字:像素 图像 并行化 | 更新日期: 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);
}
});
}
});