C#,带有IntPtr的新位图,ArgumentException

问题描述

|| 我有一个很奇怪的问题。 这是我的简化代码来解释:
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
,它似乎是由“新的Bitmap(...); \”启动的 我不明白,文档中也没有说size4 size的尺寸有限。 怎么了?还有其他方法可以做我想要的吗? 非常感谢你。     

解决方法

  大步走   类型:System.Int32   一个整数,它指定一条扫描线的起点与下一条扫描线之间的字节偏移量。这通常(但不是必须)乘以像素格式的字节数(例如,每个像素16位为2)乘以位图的宽度。传递给此参数的值必须是四的倍数。 http://msdn.microsoft.com/zh-CN/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
来说明填充。     ,
Bitmap bmp = new Bitmap(\"SomeImage\");

// Lock the bitmap\'s bits.  
Rectangle rect = new Rectangle(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,bytes);