微软的那个例子(见连接)可能有问题
http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.bitmapdata.aspx原因是跨距(Stride)可以是负数,这种情况下bmpData.Scan0将指向图像最后一行的开头。直接Marshal.Copy会出问题。BmpData.Stride见:
http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.bitmapdata.stride.aspx
http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.bitmapdata.aspx原因是跨距(Stride)可以是负数,这种情况下bmpData.Scan0将指向图像最后一行的开头。直接Marshal.Copy会出问题。BmpData.Stride见:
http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.bitmapdata.stride.aspx
{
if (this.bmpData.PixelFormat == PixelFormat.Format32bppArgb)
{
byte* numPtr = (byte*) ((((void*) this.bmpData.Scan0) + (y * this.bmpData.Stride)) + (x * 4));
return Color.FromArgb(numPtr[3], numPtr[2], numPtr[1], numPtr[0]);
}
if (this.bmpData.PixelFormat == PixelFormat.Format24bppRgb)
{
byte* numPtr2 = (byte*) ((((void*) this.bmpData.Scan0) + (y * this.bmpData.Stride)) + (x * 3));
return Color.FromArgb(numPtr2[2], numPtr2[1], numPtr2[0]);
}
return Color.Empty;
}
大量属性的调用,会耗时。实际算法里这只是优化的第一步。
for (int counter = 2; counter < rgbValues.Length; counter += 3)
rgbValues[counter] = 255;
替换为指针操作,或者不用指针操作,直接用Marshal.WriteByte
我明白你说的「内存法」就是指Copy了。。从来不用。。其实,MSDN那段我只是用来说明下Lock/Unlock的用法,和测试代码无关。测试是用指针逐像素读写的。。参考16楼。。
LockBits的存在有点类似于GDI的 GetDibits,他能够简单的把图像数据在不同格式之间进行转换。
GetPixel之类的函数的存在也不是为了专业的图像处理的,而是对类似于屏幕取色或DC取色这样小批量数据时方便处理。
要玩速度,图像处理方面的算法先是用普通语言写出来,对算法的核心尽心优化,如果速度还不行,考虑用汇编进一步优化,越简单的算法,用汇编优化的速度能提高的倍数越高,比如,最简单的反色算法,3000*4000*24的图像,一般的语言要100ms左右的处理时间,用汇编的话20ms够了,不过复杂的算法,一般汇编能提升的档次不会有这么明显。
byte* p = (byte*)ptr;
byte* q = p + rgbValues.Length;
for (byte* counter = p + 2; counter < q; counter += 3)
*counter = 255;
把两个copy去掉测试一下时间,除了时间之外还有空间的优势。
Marshal.WriteByte我说的有误,速度不快,特此更正,不好意思,哈哈。
关键还是面粉跟发酵
是的。GDI+做点简单图像做界面,真正处理还是需要更精简的方式。刚优化了下,反色 4096x4096@24bpp 的图像,用时299 ms,我已经黔驴技穷了,大家继续。PS: 3000x4000@24bpp 的图像用时 213 msSize:3000 x 4000
Processing FastBitmap...
Processed fast invert in 213 ms.
Processed FastBitmap in 213 ms.
to laviewpbt & all:最新优化,时间缩短52msto KarasCanvas:正点!我都是用的自发粉。先试试吧,不行再买酵母。
Processing FastBitmap...
Processed fast invert in 176 ms.
Processed FastBitmap in 176 ms.