直接贴代码:
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;
}