天天看点

C#使用内存法Marshal 方法和BitMapData处理任意24位彩色图像

Marshal提供了一个方法集,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法。

命名空间:System.Runtime.InteropServices

程序集:mscorlib(在 mscorlib.dll 中)

c#中Marshal.Copy方法的使用

Marshal.copy()方法用来在托管对象(数组)和非托管对象(IntPtr)之间进行内容的复制。

if (curBitmap != null)
            {
                        //位图矩形
                Rectangle rect = new Rectangle(, , curBitmap.Width, curBitmap.Height);
                //以可读写的方式锁定全部位图像素
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                //得到首地址
                IntPtr ptr = bmpData.Scan0;

                //位bmp位图字节数
                int bytes = bmpData.Stride * bmpData.Height;
                //定义位图数组
                byte[] rgbValues = new byte[bytes];
                //复制被锁定的位图像值到该数组内
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, , bytes);

                //灰度化
                double colorTemp = ;
                for (int i = ; i < bmpData.Height; i++)
                {
                    //利用公式()计算灰度值,只处理每行中是图像像素的数据,舍弃未用空间
                    for (int j = ; j < bmpData.Width * 3; j += 3)
                    {
                        colorTemp = rgbValues[i * bmpData.Stride + j + ] *  + rgbValues[i * bmpData.Stride + j + ] *  + rgbValues[i * bmpData.Stride + j] * ;//之需改动此公式就可以改变灰度化图像
                        //R=G=B
                        rgbValues[i * bmpData.Stride + j + ] = rgbValues[i * bmpData.Stride + j + ] = rgbValues[i * bmpData.Stride + j] = (byte)colorTemp;
                    }

                }
                //把数组复制回位图
     System.Runtime.InteropServices.Marshal.Copy(rgbValues, , ptr, bytes);
                //解锁位图像素
                curBitmap.UnlockBits(bmpData)

               //对窗体进行重新绘制,这将强制执行paint事件处理程序
                Invalidate();