如何使用C#将位图数据复制到字节数组中? 我想将BITMAPATIOD复制到字节[]中,但是在数组中间(索引6和7)中不存在零。我做错了什么 Bitmap bt = new Bitmap(2, 2, System.Drawing.Imaging.PixelFormat.Format24bppRgb); for(int ii = 0; ii < bt.Width; ii++) for(int jj = 0; jj < bt.Height; jj++) { int tempVal = (ii + jj * 2)*85; bt.SetPixel(ii, jj, System.Drawing.Color.FromArgb(tempVal, tempVal, tempVal)); } Rectangle rect = new Rectangle(0,0,bt.Width, bt.Height); System.Drawing.Imaging.BitmapData btData = bt.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bt.PixelFormat); IntPtr ptr = btData.Scan0; int bytes = bt.Width * bt.Height * 3; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); bt.UnlockBits(btData); for (var ii = 0; ii < bytes; ii++) System.Diagnostics.Debug.WriteLine(rgbValues[ii]); //bt.Save("test.png"); Bitmap bt=新位图(2,2,System.Drawing.Imaging.PixelFormat.Format24bppRgb); 对于(int ii=0;ii

如何使用C#将位图数据复制到字节数组中? 我想将BITMAPATIOD复制到字节[]中,但是在数组中间(索引6和7)中不存在零。我做错了什么 Bitmap bt = new Bitmap(2, 2, System.Drawing.Imaging.PixelFormat.Format24bppRgb); for(int ii = 0; ii < bt.Width; ii++) for(int jj = 0; jj < bt.Height; jj++) { int tempVal = (ii + jj * 2)*85; bt.SetPixel(ii, jj, System.Drawing.Color.FromArgb(tempVal, tempVal, tempVal)); } Rectangle rect = new Rectangle(0,0,bt.Width, bt.Height); System.Drawing.Imaging.BitmapData btData = bt.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bt.PixelFormat); IntPtr ptr = btData.Scan0; int bytes = bt.Width * bt.Height * 3; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); bt.UnlockBits(btData); for (var ii = 0; ii < bytes; ii++) System.Diagnostics.Debug.WriteLine(rgbValues[ii]); //bt.Save("test.png"); Bitmap bt=新位图(2,2,System.Drawing.Imaging.PixelFormat.Format24bppRgb); 对于(int ii=0;ii,c#,bytearray,bitmapdata,C#,Bytearray,Bitmapdata,这些零是填充,因为您使用的是格式24bpprgb格式,即每像素3字节,因此图像中每行的末尾都有一个填充。BitmapData.Stride属性返回内存中一行的大小。对于自上而下的图像,这是一个正值,对于自下而上的图像,这是一个负值。对于.NET内存位图,“始终”可以除以4 因此,如果要使用托管字节数组,可以这样做: byte[] data = new byte[Math.Abs(bitmapData.Stride * bitmapData.Height)]; Marshal.Copy(bitma

这些零是填充,因为您使用的是
格式24bpprgb
格式,即每像素3字节,因此图像中每行的末尾都有一个填充。
BitmapData.Stride
属性返回内存中一行的大小。对于自上而下的图像,这是一个正值,对于自下而上的图像,这是一个负值。对于.NET内存位图,“始终”可以除以4

因此,如果要使用托管字节数组,可以这样做:

byte[] data = new byte[Math.Abs(bitmapData.Stride * bitmapData.Height)];
Marshal.Copy(bitmapData.Scan0, data, 0, data.Length);
unsafe
{
    byte* line = (byte*)bitmapData.Scan0;
    for (int y = 0; y < data.Height; y++)
    {
        for (int x = 0; x < data.Width; x++)
        {
            byte* pos = line + x * 3;
            int pixel = Color.FromArgb(pos[0], pos[1], pos[2]).ToArgb();
            // do whatever
         }

         line += data.Stride;
     }
 }
或者,如果您使用不安全代码,您可以像下面这样扫描行:

byte[] data = new byte[Math.Abs(bitmapData.Stride * bitmapData.Height)];
Marshal.Copy(bitmapData.Scan0, data, 0, data.Length);
unsafe
{
    byte* line = (byte*)bitmapData.Scan0;
    for (int y = 0; y < data.Height; y++)
    {
        for (int x = 0; x < data.Width; x++)
        {
            byte* pos = line + x * 3;
            int pixel = Color.FromArgb(pos[0], pos[1], pos[2]).ToArgb();
            // do whatever
         }

         line += data.Stride;
     }
 }
不安全
{
字节*行=(字节*)bitmapData.Scan0;
对于(int y=0;y
这些零是填充,因为您使用的是
格式24bpprgb
格式,即每像素3字节,因此图像中每行的末尾都有一个填充。
BitmapData.Stride
属性返回内存中一行的大小。对于自上而下的图像,这是一个正值,对于自下而上的图像,这是一个负值。对于.NET内存位图,“始终”可以除以4

因此,如果要使用托管字节数组,可以这样做:

byte[] data = new byte[Math.Abs(bitmapData.Stride * bitmapData.Height)];
Marshal.Copy(bitmapData.Scan0, data, 0, data.Length);
unsafe
{
    byte* line = (byte*)bitmapData.Scan0;
    for (int y = 0; y < data.Height; y++)
    {
        for (int x = 0; x < data.Width; x++)
        {
            byte* pos = line + x * 3;
            int pixel = Color.FromArgb(pos[0], pos[1], pos[2]).ToArgb();
            // do whatever
         }

         line += data.Stride;
     }
 }
或者,如果您使用不安全代码,您可以像下面这样扫描行:

byte[] data = new byte[Math.Abs(bitmapData.Stride * bitmapData.Height)];
Marshal.Copy(bitmapData.Scan0, data, 0, data.Length);
unsafe
{
    byte* line = (byte*)bitmapData.Scan0;
    for (int y = 0; y < data.Height; y++)
    {
        for (int x = 0; x < data.Width; x++)
        {
            byte* pos = line + x * 3;
            int pixel = Color.FromArgb(pos[0], pos[1], pos[2]).ToArgb();
            // do whatever
         }

         line += data.Stride;
     }
 }
不安全
{
字节*行=(字节*)bitmapData.Scan0;
对于(int y=0;y
这是设计为位图像素阵列格式需要填充每行起始偏移量以指向4的倍数的地址

从 出于文件存储目的,只有每行的大小必须是4字节的倍数,而文件偏移量可以是任意的。[5]宽度为1的24位位图每行有3字节数据(蓝色、绿色、红色)和1字节填充,而Width=2有2字节填充,Width=3有3字节填充,而宽度=4则根本没有任何填充

顺便说一下,您的字节数计算似乎不正确,根据,应该是:

bytes = Math.Abs(btData.Stride) * bt.Height;

这是因为位图像素阵列格式需要填充每行的起始偏移量以指向4的倍数的地址

从 出于文件存储目的,只有每行的大小必须是4字节的倍数,而文件偏移量可以是任意的。[5]宽度为1的24位位图每行有3字节数据(蓝色、绿色、红色)和1字节填充,而Width=2有2字节填充,Width=3有3字节填充,而宽度=4则根本没有任何填充

顺便说一下,您的字节数计算似乎不正确,根据,应该是:

bytes = Math.Abs(btData.Stride) * bt.Height;