速度 - 将位图数据复制到数组中还是直接使用它?

时间:2013-02-12 13:50:22

标签: c# .net performance image-processing bitmap

我正在使用LockedBitmap类来简化C#中位图数据的处理。目前,它正在将数据复制到本地byte[]数组中,然后通过其类方法访问该数组以获取/设置像素颜色值。

这比直接通过指针访问锁定的位图数据更快还是更好?是否需要副本?

编辑:我不是在问是否可以直接使用位图数据,我每天都在使用它。我只是要求对两种方法进行比较,以及是否有必要复制像素数据。


将像素数据复制到临时数组中:

// create byte array to copy pixel values
int step = Depth / 8;
Pixels = new byte[PixelCount * step];
Iptr = bitmapData.Scan0;

// Copy data from pointer to array
Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);

直接读取像素值:

byte* p = (byte*)(void*)bmData.Scan0.ToPointer();
int ws = bmData.Stride;
byte* row = &p[i * ws];
byte Gcolor = row[j];
byte Bcolor = row[j + 1];
byte Rcolor = row[j + 2];

2 个答案:

答案 0 :(得分:3)

  

这比访问锁定的位图数据更快还是更好   直接通过指针?

没有。它需要一个额外的复制操作,然后另一个操作将处理后的值复制回位图。

  

是否需要复制?

仅在unsafe代码不受欢迎或不可用的环境中。

答案 1 :(得分:2)

您可以直接在位图数据上操作而无需复制它。以下是我用来将客户16bpp灰度格式转换为可显示位图的一些代码:

    Rectangle rect = new Rectangle(0, 0, bmOut.Width, bmOut.Height);
    System.Drawing.Imaging.BitmapData bmpData =
        bmOut.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
        bmOut.PixelFormat);
    IntPtr ptr = bmpData.Scan0;
    Byte[] bytes;

    bytes = rawIn.ReadBytes(framesize);

    for (int x = 0; x < bytes.Length; x += 2)
    {
        short[] rgb = new short[3];
        int value = bytes[x + 1] * 256 + bytes[x];
        //value = value / 32;
        value = iMax * (value - iMin) / (iMax - iMin);

        if (value < iMin)
        {
            value = iMin;
        }
        else if (value > iMax)
        {
            value = iMax;
        }

        value = 65536 * (value - iMin) / (iMax - iMin);

        rgb[0] = rgb[1] = rgb[2] = (short)(value);
        System.Runtime.InteropServices.Marshal.Copy(rgb, 0, ptr + (x) * 3, 3);

    }
    bmOut.UnlockBits(bmpData);

关键是LockBitsUnlockBits

作为一个快速解释,我正在从文件读取16bpp到bytes,将16位重建为value。然后,使用外部提供的iMiniMax缩放来获得正确的阴影。然后获取单个value并构建RGB并使用Marshal.Copy将其放入位图。