我一直在玩一些Image Pixelation算法,我遇到了这个post。
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;
}
一切正常,但我很难并行化(希望它是一个单词)代码。我知道你应该使用LockBits而不是,但是我真的很难做到这一点。我确信有办法做像素块/核心。
并行代码不是我的强项。
答案 0 :(得分:0)
使用找到here的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个变换为Parallel.For:
Parallel.For(xx, xx + pixelateSize, x =>
{
if (x < width)
{
Parallel.For(yy, yy + pixelateSize, y =>
{
if (y < height)
{
lockBitmap.SetPixel(x, y, pixel);
}
});
}
});