使用大图像时出现异常

本文关键字:异常 图像 | 更新日期: 2023-09-27 18:20:30

我在C#中开发了一个迷宫生成器,它生成大迷宫,然后将它们保存到png文件中。

目前,我在尝试保存图像时遇到了一些错误。

当我使用这个:

System.Drawing.Bitmap tempBitmap = new System.Drawing.Bitmap(16000, 16000);

我得到一个论点例外。(它确实适用于8000*8000)

当我使用WPF的方式:

RenderTargetBitmap rtb = 
              new RenderTargetBitmap(16000, 16000, 96, 96, PixelFormats.Pbgra32);

我遇到内存溢出异常。

有人有其他方法可以在c#中保存大图像吗?

我也看过一些图书馆,但没有成功。

有人还说,我应该先把图像分成几个部分保存,然后再把它们组合起来,但我怎么能做到这一点呢?

编辑:

第2版:我现在正在尝试PixelFormat.Format1ppp索引如下:

private Bitmap CreateBitmapImage2(BitArray[] map, List<Point> path)
{
    Bitmap objBmpImage = new Bitmap(cursize * (map[0].Length - 1), cursize * (map.Length - 1), PixelFormat.Format1bppIndexed);
    Rectangle rect = new Rectangle(0, 0, objBmpImage.Width, objBmpImage.Height);
    System.Drawing.Imaging.BitmapData bmpData =
        objBmpImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
        objBmpImage.PixelFormat);
    IntPtr ptr = bmpData.Scan0;
    int bytes = Math.Abs(bmpData.Stride) * objBmpImage.Height;
    byte[] rgbValues = new byte[bytes];
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
    int counter = 0;
    int counterdeluxe = 0;
    BitArray bitarray = new BitArray(8);
    Random r = new Random();
    Boolean last = true;
    for (int i = 0; i < 225 / 8; i++)
    {
        rgbValues[i] = (byte)r.Next(255);
    }
    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

    objBmpImage.UnlockBits(bmpData);
    return (objBmpImage);
}

尽管出于某种原因,它只创建了一半的图像:http://dl.dropbox.com/u/1814002/maze.png

第4版:啊,宽度中的位似乎总是四舍五入到一个4字节的数字。现在它开始对我有意义了:)。

第5版:好吧,这已经没有意义了,哈哈,我现在只停留在图形上,我想

第6版:我无法释怀,所以我又看了一遍,发现了以下内容:在我使用BitArray将单独的位转换为一个字节,然后将其写入ImageData时,出现了问题,显然必须反向写入位数组。终于一切正常了:)。

所有问题都解决了,我的迷宫生成器也开始运行了。感谢大家:)

使用大图像时出现异常

如果你的迷宫只是黑/白的,你可能想试试:

Bitmap bitmap = new Bitmap(16000, 16000, PixelFormat.Format1bppIndexed);

假设它在内存中保持该格式的图像,那么它应该比默认的像素格式效率高得多。

在我的盒子上(诚然,它有12GB的内存),默认情况下16000x16000可以工作,但32000x3200不行。即使是32000x3200也可以与Format1bppIndexed配合使用。

EDIT:如注释中所述,应该对位图使用using语句:

using (Bitmap bitmap = ...)
{
}

从而可以适当地清洁它们。