Gin*_*nko 1 c# parallel-processing multithreading system.drawing
好吧,我有一个代码在"x"图像中应用Rain Bow过滤器,我必须以两种方式做:顺序和并行,我的顺序代码工作没有问题,但并行部分不起作用.我不知道,为什么?
码
public static Bitmap RainbowFilterParallel(Bitmap bmp)
{
Bitmap temp = new Bitmap(bmp.Width, bmp.Height);
int raz = bmp.Height / 4;
Parallel.For(0, bmp.Width, i =>
{
Parallel.For(0, bmp.Height, x =>
{
if (i < (raz))
{
temp.SetPixel(i, x, Color.FromArgb(bmp.GetPixel(i, x).R / 5, bmp.GetPixel(i, x).G, bmp.GetPixel(i, x).B));
}
else if (i < (raz * 2))
{
temp.SetPixel(i, x, Color.FromArgb(bmp.GetPixel(i, x).R, bmp.GetPixel(i, x).G / 5, bmp.GetPixel(i, x).B));
}
else if (i < (raz * 3))
{
temp.SetPixel(i, x, Color.FromArgb(bmp.GetPixel(i, x).R, bmp.GetPixel(i, x).G, bmp.GetPixel(i, x).B / 5));
}
else if (i < (raz * 4))
{
temp.SetPixel(i, x, Color.FromArgb(bmp.GetPixel(i, x).R / 5, bmp.GetPixel(i, x).G, bmp.GetPixel(i, x).B / 5));
}
else
{
temp.SetPixel(i, x, Color.FromArgb(bmp.GetPixel(i, x).R / 5, bmp.GetPixel(i, x).G / 5, bmp.GetPixel(i, x).B / 5));
}
});
});
return temp;
}
Run Code Online (Sandbox Code Playgroud)
此外,稍后程序返回相同的错误,但说"对象已在使用中".
PS.我是c#的初学者,我在另一篇文章中搜索了这个主题,但我一无所获.
非常感谢你提前
正如评论者Ron Beyer指出的那样,使用SetPixel()和GetPixel()方法非常缓慢.对这些方法之一的每次调用都会在托管代码到对象所代表的实际二进制缓冲区之间的转换过程中产生大量开销Bitmap.那里有很多层,视频驱动程序通常涉及到需要在用户和内核级执行之间进行转换.
但是除了速度慢之外,这些方法也会使对象"忙",因此如果在调用这些方法之一和返回时(即,当它们之间)尝试使用位图(包括调用其中一个方法)时调用正在进行中),您看到的异常会发生错误.
由于并行化当前代码的唯一方法是有用的,如果这些方法调用可以同时发生,并且由于它们根本不能,这种方法不会起作用.
另一方面,使用该LockBits()方法不仅可以保证工作,您很可能会发现性能更好LockBits(),甚至不需要并行化算法.但是,如果您决定这样做,由于工作方式LockBits()- 您可以访问表示位图图像的原始字节缓冲区 - 您可以轻松地并行化算法并利用多个CPU核心(如果存在).
请注意,在使用时,LockBits()您将使用您Bitmap可能不习惯的级别的对象.如果您还不了解位图如何在"引擎盖下"工作,那么您将不得不熟悉位图实际存储在内存中的方式.这包括了解不同像素格式的含义,如何解释和修改给定格式的像素,以及如何在内存中布置位图(例如,行的顺序,可以根据位图而变化,以及"大步"的位图".
这些东西并不是很难学,但需要耐心.如果性能是您的目标,那么值得付出努力.
| 归档时间: |
|
| 查看次数: |
1284 次 |
| 最近记录: |