我如何使用位图大.NET中? [英] How do I use large bitmaps in .NET?

查看:145
本文介绍了我如何使用位图大.NET中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着写一个轻量级的图像浏览应用程序。不过,也有与.NET系统内存限制。

I'm trying to write a light-weight image viewing application. However, there are system memory limitations with .NET.

当试图加载大位图( 9000点¯x9000像素或更大,24位),我得到一个System.OutOfMemoryException。这是一个Windows 2000的PC 2GB的RAM(其中1.3GB用完为止)上。它也需要大量的时间以试图加载文件

When trying to load large bitmaps (9000 x 9000 px or larger, 24-bit), I get a System.OutOfMemoryException. This is on a Windows 2000 PC with 2GB of RAM (of which 1.3GB is used up). It also takes a lot of time to attempt loading the files.

以下code生成此错误:

The following code generates this error:

Image image = new Bitmap(filename);
using (Graphics gfx = this.CreateGraphics())
{
    gfx.DrawImage(image, new Point(0, 0));
}

至于这是否code:

As does this code:

Stream stream = (Stream)File.OpenRead(filename);
Image image = Image.FromStream(stream, false, false);
using (Graphics gfx = this.CreateGraphics())
{
    gfx.DrawImage(image, new Rectangle(0, 0, 100, 100), 4000, 4000, 100, 100, GraphicsUnit.Pixel);
}

此外,它是不够的,只是这做的事:

Also, it is enough to do just this:

Bitmap bitmap = new Bitmap(filename);
IntPtr handle = bitmap.GetHbitmap();

后者code是用于与GDI使用。
虽然研究这个,我发现,这其实就是.NET的地方尝试分配的两倍多,因为需要在一个单独的内存块contigous内存问题。

The latter code was intended for use with GDI. While researching this, I found out that this is in fact a memory issue where .NET tries to allocate twice as much as is needed in a single contigous block of memory.

<一个href=\"http://bytes.com/groups/net-c/279493-drawing-large-bitmaps\">http://bytes.com/groups/net-c/279493-drawing-large-bitmaps

我从其他应用程序知道(IE浏览器,MS涂料等),有可能打开大的图像,并相当迅速。我的问题是, 我如何使用位图大使用.NET?

I know from other applications (Internet Explorer, MS Paint etc.) that it IS possible to open large images, and rather quickly. My question is, how do I use large bitmaps with .NET?

反正有他们流,或者非记忆负荷呢?

Is there anyway to stream them, or non-memory load them?

推荐答案

这是一个问题的两个部分。第一个问题是如何加载大图像,而运行内存(1),第二个是提高负荷性能(2)。

This is a two part question. The first question is how you can load large images without running out of memory (1), the second one is on improving loading performance (2).

(1)海外商品会有如Photoshop,你有巨大的图像消费上的文件系统gigabites工作能力的应用程序。在内存中保存整个图像,仍然有足够的可用内存来执行操作(过滤器,图像处理等等,甚至只是添加层)将在大多​​数系统(甚至8GB的x64系统)是不可能的。

(1) Concider an application like Photoshop where you have the ability to work with huge images consuming gigabites on the filesystem. Keeping the entire image in memory and still have enough free memory to perform operations (filters, image processing and so on, or even just adding layers) would be impossible on most systems (even 8gb x64 systems).

这就是为什么应用程序,如这里使用的交换文件的概念。在内部我假设的Photoshop使用专有的文件格式,适合其应用的设计和建造,以支持部分负荷从交换,使他们到一个文件的部分加载到内存来处理它。

That is why applications such as this uses the concept of swap files. Internally I'm assuming that photoshop uses a proprietary file format, suitable for their application design and built to support partial loads from the swap, enabling them to load parts of a file into memory to process it.

(2)能Performande通过编写定制的装载机为每个文件格式可以改善(相当多)。这需要你对你要使用的文件格式的文件头和结构念起来。一旦你得到了它的手它不是 ** **那个很难,但它不是做一个方法调用微不足道。

(2) Performande can be improved (quite a lot) by writing custom loaders for each file format. This requires you to read up on the file headers and structure of the file formats you want to work with. Once you've gotten the hand of it its not **that** hard, but it's not as trivial as doing a method call.

例如,你可以谷歌FastBitmap看到你如何加载位图(BMP)的例子文件速度非常快,它包括位图标头解码。这涉及的PInvoke,并给予你你是什么了一些想法对你需要定义位图structues如

For example you could google for FastBitmap to see examples on how you can load a bitmap (BMP) file very fast, it included decoding the bitmap header. This involved pInvoke and to give you some idea on what you are up against you will need to define the bitmap structues such as

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct BITMAPFILEHEADER
        {
            public Int16 bfType;
            public Int32 bfSize;
            public Int16 bfReserved1;
            public Int16 bfReserved2;
            public Int32 bfOffBits;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct BITMAPINFO
        {
            public BITMAPINFOHEADER bmiHeader;
            public RGBQUAD bmiColors;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct BITMAPINFOHEADER
        {
            public uint biSize;
            public int biWidth;
            public int biHeight;
            public ushort biPlanes;
            public ushort biBitCount;
            public BitmapCompression biCompression;
            public uint biSizeImage;
            public int biXPelsPerMeter;
            public int biYPelsPerMeter;
            public uint biClrUsed;
            public uint biClrImportant;
        }

有可能创建一个DIB(<一工作href=\"http://www.herdsoft.com/ti/davincie/imex3j8i.htm\">http://www.herdsoft.com/ti/davincie/imex3j8i.htm)和古怪像一个位图被存储倒挂的数据,你需要考虑到,否则你会看到一个镜像当U打开它: - )

Possibly work with creating a DIB (http://www.herdsoft.com/ti/davincie/imex3j8i.htm) and oddities like data being stored "upside down" in a bitmap which you need to take into account or you'll see a mirror image when u open it :-)

现在这还只是位图。假设你想要做PNG那么你需要做类似的东西,但在PNG头,解码其最简单的形式的心不是那么难,但如果你想获得全面PNG规范的支持,那么你是一个有趣的旅程: - )

Now that's just for bitmaps. Say you wanted to do PNG then you'd need to do similar stuff but decoding the PNG header, which in its simplest form isnt that hard, but if you want to get full PNG specification support then you are in for a fun ride :-)

PNG不同的是说一个位图,因为它使用了基于块格式,其中有头,你可以loacate发现有多种不同的数据。一些大块的例子中,我使用,而与格式打得

PNG is different to say a bitmap since it uses a chunk based format where it has "headers" you can loacate to find the diffrent data. Example of some chunks I used while playing with the format was

    string[] chunks =  
new string[] {"?PNG", "IHDR","PLTE","IDAT","IEND","tRNS",
"cHRM","gAMA","iCCP","sBIT","sRGB","tEXt","zTXt","iTXt",
"bKGD","hIST","pHYs","sPLT","tIME"};

您也将有机会了解的Adler32校验和PNG文件。因此,每个文件格式你想要做将增加一个不同的挑战。

You are also going to have to learn about Adler32 checksums for PNG files. So each file format you'd want to do would add a different set of challenges.

我真希望我能给予更多的完整的源代码code例子,我的答复,但它是一个复杂的问题,并说实话我还没有实施交换自己,所以我就不能给予太多的固建议上。

I really wish I could give more complete source code examples in my reply but it's a complex subject, and to be honest I've not implemented a swap myself so I wouldn't be able to give too much solid advice on that.

简短的回答是,在BCL图像处理cababilities是不是很烫。介质的答案是尝试和发现,如果有人写了一个图像库,可以帮助您和长期的答案是拉起你的袖子,写你自己的应用程序的核心。

The short answer is that the image processing cababilities in the BCL isn't that hot. The medium answer would be to try and find if someone has written an image library that could help you and the long answer would be to pull up your sleeves and write the core of your application yourself.

既然你知道我在现实生活中,你知道在哪里可以找到我;)

Since you know me in real-life you know where to find me ;)

这篇关于我如何使用位图大.NET中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆