我有一个非常奇怪的问题。
以下是我的简化代码解释:
class Bitmap1
{
public Bitmap nImage;
public IntPtr data;
public Bitmap1()
{
int w = 2450;
int h = 2450;
this.data = Marshal.AllocHGlobal(w*h);
nImage = new Bitmap(w, h, w, PixelFormat.Format8bppIndexed, data);
}
}
当w
和h
等于 2448 时,如果我调用构造函数,一切都会正常运行。
但是当h和w等于 2450 时,我有一个ArgumentException
似乎是由“新位图(...)”启动的;
我无法理解,文档并未说明Marshal.AllocHGlobal
的篇幅有限。
怎么了?还有其他方法可以做我想要的吗?
非常感谢。
答案 0 :(得分:5)
步幅 键入:System.Int32 整数,指定一条扫描线的开头与下一条扫描线之间的字节偏移量。这通常(但不是必须)像素格式中的字节数(例如,每像素16位的2)乘以位图的宽度。 传递给此参数的值必须是四的倍数 ..
http://msdn.microsoft.com/en-us/library/zy1a2d14.aspx
所以你需要以下内容:
int w = 2450;
int h = 2450;
int s = 2452;//Next multiple of 4 after w
this.data = Marshal.AllocHGlobal(s*h);
nImage = new Bitmap(w, h, s, PixelFormat.Format8bppIndexed, data);
这意味着每行之间只有2个字节,只是填充而不是位图本身的一部分。在进行指针运算时,您显然需要s*y+x
而不是w*y+x
来考虑填充。
答案 1 :(得分:1)
Bitmap bmp = new Bitmap("SomeImage");
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
Marshal.Copy(ptr, rgbValues, 0, bytes);