C# 将位图数据复制到Int32数组时发生访问冲突
我想将24位彩色位图数据复制到Int32数组中,并编写了以下代码C# 将位图数据复制到Int32数组时发生访问冲突,c#,bitmap,bitmapdata,C#,Bitmap,Bitmapdata,我想将24位彩色位图数据复制到Int32数组中,并编写了以下代码 Width of image = 200 pixels Height of image = 150 pixels public static Int32[] readBitmap() { int rows = 150; int columns = 200; Bitmap myBmp = new Bitmap("puppy.bmp"); BitmapDa
Width of image = 200 pixels
Height of image = 150 pixels
public static Int32[] readBitmap()
{
int rows = 150;
int columns = 200;
Bitmap myBmp = new Bitmap("puppy.bmp");
BitmapData bmd = myBmp.LockBits(new Rectangle(0, 0, columns, rows), ImageLockMode.ReadWrite, myBmp.PixelFormat);
Console.WriteLine(myBmp.PixelFormat.ToString());
int fileSize = 30000; // 200 * 150
Int32[] fileBufferArray = new Int32[fileSize];
unsafe
{
for (int j = 0; j < rows; j++)
{
Int32* row = (Int32*)bmd.Scan0 + (j * bmd.Stride);
for (int i = 0; i < columns; i++)
{
try
{
fileBufferArray[j * columns + i] = row[i];
}
catch (Exception e)
{
Console.WriteLine(e.ToString() + " " + i.ToString() + " " + j.ToString());
break;
}
}
}
myBmp.UnlockBits(bmd);
return fileBufferArray;
} //unsafe
}
有人能帮我纠正这个错误吗?问题是一个有30000像素的位图需要3*30000字节以24位颜色表示。每个像素由三个字节表示。循环正在将字节复制为整数。由于整数数组的长度只有30000个整数,它将失败 如果你写过:
var fileBufferArray = new int[30000];
for (int i = 0; i < 90000; ++i)
{
fileBufferArray[i] = bitmapData[i];
}
var fileBufferArray=newint[30000];
对于(int i=0;i<90000;++i)
{
fileBufferArray[i]=位图数据[i];
}
显然,这将失败
您需要将每三个字节组合成一个24位值。一种方法是将内部循环中的赋值更改为:
int r = i * 3;
int pixelvalue = row[r];
pixelValue = (pixelValue << 8) | row[r+1];
pixelValue = (pixelValue << 8) | row[r+2];
fileBufferArray[j * columns + i] = pixelValue;
intr=i*3;
int pixelvalue=行[r];
pixelValue=(pixelValue问题在于,具有30000像素的位图需要3*30000字节以24位颜色表示。每个像素由三个字节表示。您的循环正在将字节复制到整数。由于整数数组的长度只有30000个整数,因此将失败
如果你写过:
var fileBufferArray = new int[30000];
for (int i = 0; i < 90000; ++i)
{
fileBufferArray[i] = bitmapData[i];
}
var fileBufferArray=newint[30000];
对于(int i=0;i<90000;++i)
{
fileBufferArray[i]=位图数据[i];
}
显然,这将失败
您需要将每三个字节合并为一个24位值。一种方法是将内部循环中的赋值更改为:
int r = i * 3;
int pixelvalue = row[r];
pixelValue = (pixelValue << 8) | row[r+1];
pixelValue = (pixelValue << 8) | row[r+2];
fileBufferArray[j * columns + i] = pixelValue;
intr=i*3;
int pixelvalue=行[r];
pixelValue=(pixelValue您正在溢出fileBufferArray。请查看此更通用的方法是否可以帮助您。该方法:
使用流获取字节数组还有更安全的方法:
private byte[] BmpToBytes(Bitmap bmp)
{
MemoryStream ms = new MemoryStream();
// Save to memory using the bmp format
bmp.Save (ms, ImageFormat.Bmp);
// read to end
byte[] bmpBytes = ms.GetBuffer();
bmp.Dispose();
ms.Close();
return bmpBytes;
}
您正在溢出fileBufferArray。请查看此更通用的方法是否可以帮助您。该方法:
使用流获取字节数组还有更安全的方法:
private byte[] BmpToBytes(Bitmap bmp)
{
MemoryStream ms = new MemoryStream();
// Save to memory using the bmp format
bmp.Save (ms, ImageFormat.Bmp);
// read to end
byte[] bmpBytes = ms.GetBuffer();
bmp.Dispose();
ms.Close();
return bmpBytes;
}
嗨,我用了一个30000长度的整数数组,不是吗3000@user581734:谢谢你的更正。你是对的,30000。答案仍然有效。位图数据数组有90000个值,你试图将它们复制到30000个值的数组中。它将失败。嗨,我使用了一个30000长度的int数组。不是3000@user581734:谢谢你的正确回答ion.你说得对,30000。答案仍然有效。位图数据数组有90000个值,你正试图将它们复制到一个包含30000个值的数组中。这将失败。嘿,我怎么能溢出fileBufferArray?它的大小等于位图图像。@user581734:不,位图图像有30000个像素,但需要90000字节才能复制表示这些像素。您可以通过bmd.Height*bmd.Stride
计算图像的大小(以字节为单位)。对于24位图像,这将是图像大小(以像素为单位)的三倍:bmd.Height*bmd.Width
。您确定这会起作用吗?保存为bmp格式仍然包括位图标题,不是吗?您仍然不需要o解析位图标题以获取高度、宽度、跨距和指向像素数据的指针。嘿,我如何溢出fileBufferArray?其大小等于位图图像。@user581734:否,位图图像有30000像素,但需要90000字节来表示这些像素。您可以通过bmd以字节为单位计算图像的大小.Height*bmd.Stride
。对于24位图像,这将是图像大小(以像素为单位)的三倍:bmd.Height*bmd.Width
。确实可以吗?保存为bmp格式仍然包括位图标头,不是吗?您仍然需要解析位图标头以获得高度、宽度、跨距和指向pi的指针像素数据。