.net 如何访问位图图像中的每个字节

.net 如何访问位图图像中的每个字节,.net,image,bmp,.net,Image,Bmp,假设我有一个位图图像,是否可以遍历图像中的所有单个字节?如果是,怎么做?我发现: 如果您可以使用Memorystream和.Save方法,则如下所示: System.Drawing.Bitmap bmp = GetTheBitmap(); System.IO.MemoryStream stream = new System.IO.MemoryStream(); bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); stream.Pos

假设我有一个位图图像,是否可以遍历图像中的所有单个字节?如果是,怎么做?

我发现:

如果您可以使用Memorystream和.Save方法,则如下所示:

System.Drawing.Bitmap bmp = GetTheBitmap();
System.IO.MemoryStream stream = new System.IO.MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
stream.Position = 0;
byte[] data = new byte[stream.Length];
stream.Read(data, 0, stream.Length);
    BitmapData data;
    int x = 0; //or whatever
    int y = 0;
    unsafe
    {
        byte* row = (byte*)data.Scan0 + (y * data.Stride);
        int columnOffset = x * 4;
        byte B = row[columnOffset];
        byte G = row[columnOffset + 1];
        byte R = row[columnOffset + 2];
        byte A = row[columnOffset + 3];
    }

使用Bitmap类上的LockBits成员获取BitmapData,然后使用Scan0和Marshal.ReadByte获取readbytes。下面是一个小例子(但不是关于正确的亮度调整):

公共静态亮度(位图图像,整数亮度)
{
整数偏移=0;
亮度=(亮度*255)/100;
//GDI+仍然取决于我们-返回格式是BGR,而不是RGB。
BitmapData bmData=image.LockBits(新矩形(0,0,image.Width,image.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
int stride=bmData.stride;
IntPtr Scan0=bmData.Scan0;
int nVal=0;
int nOffset=步幅-图像宽度*3;
int nWidth=image.Width*3;
对于(int y=0;y255)
nVal=255;
Marshal.WriteByte(扫描0,偏移量,(字节)nVal);
++抵消;
}
偏移量+=无偏移量;
}
图像。解锁位(bmData);
}

如果需要访问像素信息,超慢但超简单的方法是在位图对象上调用GetPixel和SetPixel方法

超快速且不是那么困难的方法是调用位图的LockBits方法,并使用从中返回的BitmapData对象直接读取和写入位图的字节数据。您可以像Ilya的示例中那样使用封送处理类完成后一部分,也可以像下面这样跳过封送处理开销:

System.Drawing.Bitmap bmp = GetTheBitmap();
System.IO.MemoryStream stream = new System.IO.MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
stream.Position = 0;
byte[] data = new byte[stream.Length];
stream.Read(data, 0, stream.Length);
    BitmapData data;
    int x = 0; //or whatever
    int y = 0;
    unsafe
    {
        byte* row = (byte*)data.Scan0 + (y * data.Stride);
        int columnOffset = x * 4;
        byte B = row[columnOffset];
        byte G = row[columnOffset + 1];
        byte R = row[columnOffset + 2];
        byte A = row[columnOffset + 3];
    }

另一种解决方案是使用LockBits和Marshal.Copy将位图转换为数组。我需要这个解决方案,因为我有两个图像,只是颜色深度不同,而其他提供的解决方案处理得不好(或者太慢)

使用(位图bmp=新位图(fname)){
//将图像转换为int32数组,每个int为一个像素
int cnt=bmp.Width*bmp.Height*4/4;
BitmapData bmData=bmp.LockBits(新矩形(0,0,bmp.Width,bmp.Height),
ImageLockMode.ReadOnly,PixelFormat.Format32bppArgb);
Int32[]rgbValues=新的Int32[cnt];
//将RGB值复制到数组中。
System.Runtime.InteropServices.Marshal.Copy(bmData.Scan0,rgbvalue,0,cnt);
bmp.解锁位(bmData);
对于(int i=0;i
是的,我想1像素=1字节?1像素=x位(其中x是图像的颜色深度),谢谢你的回答。我建议这个答案的读者也读一读。这对我有额外的帮助。