直接贴代码:
private void FrmP2P_OnVideoDataCallBack(int userId, IntPtr buf, int len, AnyChatCoreSDK.BITMAPINFOHEADER bitMap, int userValue) { if(userId == m_myUserID) { byte[] pixelValues = new byte[len]; Marshal.Copy(buf, pixelValues, 0, len); Bitmap result = new Bitmap(bitMap.biWidth, bitMap.biHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb); Rectangle rect = new Rectangle(0, 0, bitMap.biWidth, bitMap.biHeight); BitmapData bmpData = result.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); IntPtr iPtr = bmpData.Scan0; //反转数组 //Array.Reverse(pixelValues); Marshal.Copy(pixelValues, 0, iPtr, len); result.UnlockBits(bmpData); //旋转180度 result.RotateFlip(RotateFlipType.Rotate180FlipNone); //显示到图片控件中 pictureBox1.Image = result; } }
================================================================================================================================
网上找到的资料:
public static bool GetRGB(Bitmap Source, out int[,] R, out int[,] G, out int[,] B) { try { int iWidth = Source.Width; int iHeight = Source.Height; Rectangle rect = new Rectangle(0, 0, iWidth, iHeight); System.Drawing.Imaging.BitmapData bmpData = Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat); IntPtr iPtr = bmpData.Scan0; int iBytes = iWidth * iHeight * 3; byte[] PixelValues = new byte[iBytes]; System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes); Source.UnlockBits(bmpData); // 注意这个地方图像的两维方向与数组两维的方向是转置的关系 R = new int[iHeight, iWidth]; G = new int[iHeight, iWidth]; B = new int[iHeight, iWidth]; int iPoint = 0; for (int i = 0; i < iHeight; i++) { for (int j = 0; j < iWidth; j++) { // 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB! B[i, j] = Convert.ToInt32(PixelValues[iPoint++]); G[i, j] = Convert.ToInt32(PixelValues[iPoint++]); R[i, j] = Convert.ToInt32(PixelValues[iPoint++]); } } return true; } catch (Exception) { R = null; G = null; B = null; return false; } } /*提醒注意的是,这段代码仅仅适合于像素是24位RGB的图像(8位R、8位B和8位G,不包含Alpha通道,Format24bppRgb),如果要其它像素格式的(可以参见System.Drawing.Imaging.PixelFormat的成员),可以此类推,加上一组case语句,成为完整功能的读图方法。 回写则与之相反,把需要写入的像素信息先写到byte数组中,再调用Marshal.Copy的第一个重载方法即可。下面给出我从灰度矩阵构建Bitmap类的方法:*/ /// <summary> /// 由灰度矩阵创建位图 /// </summary> /// <param name="Gray">灰度矩阵(取值0~255)</param> /// <returns>矩阵对应的位图</returns> public static Bitmap FromGray(int[,] Gray) { int iWidth = Gray.GetLength(1); int iHeight = Gray.GetLength(0); Bitmap Result=new Bitmap(iWidth,iHeight,System.Drawing.Imaging.PixelFormat.Format24bppRgb); Rectangle rect=new Rectangle(0,0,iWidth,iHeight); System.Drawing.Imaging.BitmapData bmpData = Result.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); IntPtr iPtr = bmpData.Scan0; int iStride = bmpData.Stride; int iBytes = iWidth * iHeight * 3; byte[] PixelValues = new byte[iBytes]; int iPoint=0; for (int i=0;i<iHeight;i++) for (int j = 0; j < iWidth; j++) { int iGray = Gray[i, j]; PixelValues[iPoint] = PixelValues[iPoint + 1] = PixelValues[iPoint + 2] = Convert.ToByte(iGray); iPoint += 3; } System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes); Result.UnlockBits(bmpData); return Result; }