我正在使用类似this answer的方法从字节数组创建位图。
private static void MySaveBMP(byte[] buffer, int width, int height)
{
Bitmap b = new Bitmap(width, height, PixelFormat.Format24bppRgb);
Rectangle BoundsRect = new Rectangle(0, 0, width, height);
BitmapData bmpData = b.LockBits(BoundsRect,
ImageLockMode.WriteOnly,
b.PixelFormat);
IntPtr ptr = bmpData.Scan0;
// fill in rgbValues
Marshal.Copy(buffer, 0, ptr, buffer.Length);
b.UnlockBits(bmpData);
b.Save(@"D:\myPic.bmp", ImageFormat.Bmp);
}
我生成一个字节数组,填写一些像这样的值:
int width = 20;
int height = 30;
int bytesPerPixel = 3;
int bytesPerRow = width * bytesPerPixel;
int totalLength = bytesPerRow * height;
byte[] managedArray = new byte[totalLength];
// fill background with white
for (int i = 0; i < totalLength; i++)
managedArray[i] = 255;
// draw on each row
for (int i = 0; i < height; i++)
{
// first pixel is green
managedArray[0 + i * bytesPerRow] = 0;
managedArray[1 + i * bytesPerRow] = 255;
managedArray[2 + i * bytesPerRow] = 0;
// last pixel is red
managedArray[bytesPerRow - 3 + i * bytesPerRow] = 0;
managedArray[bytesPerRow - 2 + i * bytesPerRow] = 0;
managedArray[bytesPerRow - 1 + i * bytesPerRow] = 255;
}
MySaveBMP(managedArray, width, height);
生成的20x30 bmp图像如下所示:
但是,如果我更改图像高度(例如,更改为21),则生成的图像似乎已损坏。 每一行看起来都向左移动了一点:
制作位图图像时我做错了什么?
答案 0 :(得分:1)
我想我找到了答案。
因为我不知道BitmapData.Stride
属性。有人有答案here.
我修改过的保存功能在这里:
private static void MySaveBMP(byte[] buffer, int width, int height)
{
Bitmap b = new Bitmap(width, height, PixelFormat.Format24bppRgb);
Rectangle BoundsRect = new Rectangle(0, 0, width, height);
BitmapData bmpData = b.LockBits(BoundsRect,
ImageLockMode.WriteOnly,
b.PixelFormat);
IntPtr ptr = bmpData.Scan0;
// add back dummy bytes between lines, make each line be a multiple of 4 bytes
int skipByte = bmpData.Stride - width*3;
byte[] newBuff = new byte[buffer.Length + skipByte*height];
for (int j = 0; j < height; j++)
{
Buffer.BlockCopy(buffer, j * width * 3, newBuff, j * (width * 3 + skipByte), width * 3);
}
// fill in rgbValues
Marshal.Copy(newBuff, 0, ptr, newBuff.Length);
b.UnlockBits(bmpData);
b.Save(@"D:\myPic.bmp", ImageFormat.Bmp);
}
另一个解决方案是,我将PixelFormat
更改为Format32bppPArgb
,并将bytesPerPixel
更改为4.因此,我不需要打扰4字节扫描线格式。