微软的那个例子(见连接)可能有问题
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

解决方案 »

  1.   

    前段时间试过Cimage里面的GetPixel,直接内存操作,当时效率提升20倍。想来也差不多了。感谢内存白菜价。
      

  2.   

    在实际的程序里如果出现这样的东西,还是慢。public unsafe Color GetPixel(int x, int y)
    {
        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;
    }
    大量属性的调用,会耗时。实际算法里这只是优化的第一步。
      

  3.   

    一直是听说,直接 Pixel 操作速度会很慢,一直都没接触过,现在感觉速度还能接受啊
      

  4.   

    类时经常会用到GetPixel和SetPixel,但是这两个方法直接使用都比较慢,所以一般都会使用LockBits/UnlockBits将位图在内存中锁定,以加快操作速
      

  5.   

    C#图像处理有三种方法,1是GetPixel,SetPixel方法,这种方法最慢,简直就是看幻灯片;2是内存法,就是你介绍的那个方法,这个方法比方法1快了N倍;3是指针法,虽然C#中指针属于不安全因素,但是,这种方法的速度确实是内存法的10倍以上!建议如果做大型图像处理操作,还是用指针法好!
      

  6.   

    我一般是用unsafe的,回头试试Marshal~
      

  7.   

    不就是个buffer吧,直接定位到那里写就行了,没这么多事!
      

  8.   

    这个不需要实验,把两个copy去掉,它不但浪费了两次copy的时间,还付出了空间的代价。在下面的代码中
    for (int counter = 2; counter < rgbValues.Length; counter += 3)
         rgbValues[counter] = 255;
    替换为指针操作,或者不用指针操作,直接用Marshal.WriteByte
      

  9.   


    我明白你说的「内存法」就是指Copy了。。从来不用。。其实,MSDN那段我只是用来说明下Lock/Unlock的用法,和测试代码无关。测试是用指针逐像素读写的。。参考16楼。。
      

  10.   

        GDIPLUS这种 LockBits是临时性的把图像的数据读到内存,是不适合于做专业的图像处理软件的,专业做的话一个图像加载后在内存呢中的格式应该是固定的,这样做算法也就是直接访问这段内存的数据。
        LockBits的存在有点类似于GDI的 GetDibits,他能够简单的把图像数据在不同格式之间进行转换。
        GetPixel之类的函数的存在也不是为了专业的图像处理的,而是对类似于屏幕取色或DC取色这样小批量数据时方便处理。
        要玩速度,图像处理方面的算法先是用普通语言写出来,对算法的核心尽心优化,如果速度还不行,考虑用汇编进一步优化,越简单的算法,用汇编优化的速度能提高的倍数越高,比如,最简单的反色算法,3000*4000*24的图像,一般的语言要100ms左右的处理时间,用汇编的话20ms够了,不过复杂的算法,一般汇编能提升的档次不会有这么明显。
      

  11.   

    我没说“内存法”,那是另一个人。不过我还是测试了一下指针和copy的速度比较,比如那段代码改为
    byte* p = (byte*)ptr;
    byte* q = p + rgbValues.Length;
    for (byte* counter = p + 2; counter < q; counter += 3)
                    *counter = 255;
    把两个copy去掉测试一下时间,除了时间之外还有空间的优势。
    Marshal.WriteByte我说的有误,速度不快,特此更正,不好意思,哈哈。
      

  12.   

    葱油饼做法 http://home.meishichina.com/recipe-22694.html
    关键还是面粉跟发酵
      

  13.   


    是的。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.
      

  14.   

    to lizhibin11:收到。
    to laviewpbt & all:最新优化,时间缩短52msto KarasCanvas:正点!我都是用的自发粉。先试试吧,不行再买酵母。
      

  15.   

    3000x4000@24bpp 的图像用时 176 msSize:3000 x 4000
    Processing FastBitmap...
    Processed fast invert in 176 ms.
    Processed FastBitmap in 176 ms.