加载文件到一个位图,但保留原来的文件保持不变文件、位图、加载

2023-09-03 00:33:13 作者:つ ℡。滚

如何做到这一点在C#?

How to do this in C#?

如果我用Bitmap.FromFile(),原来的文件被锁定。

If I use Bitmap.FromFile(), the original file is locked.

如果我用Bitmap.FromStream(),原始文件没有被锁定,但文件说,你必须保持流打开图像的寿命。这可能意味着该文件现在依然与该图象对象,(例如,或许如果文件改变,以便执行对象或反之亦然)。

If I use Bitmap.FromStream(), the original file is not locked, but the documentation says "You must keep the stream open for the lifetime of the Image." This probably means that the file is still linked to the image object, (for example, perhaps if the file change so do the object or vice versa).

我想要做的就是读取位图并将其保存到一个对象,之后有任何的文件和Image对象之间没有任何联系。

what i want to do is just reading the bitmap and save it to an object and after that there is no link whatsoever between the file and the Image object

推荐答案

在这种行为的一些背景资料:位图使用内存映射文件来访问像素的位图。这是在Windows API中一个非常基本的工具,它允许存储到文件的数据非常高效的映射。数据从文件中读取,只有当程序读取内存,虚拟内存的页面不参加​​Windows页面文件的任何空间。

Some background info on this behavior: Bitmap uses a memory-mapped file to access the pixels in the bitmap. That's a very basic facility in the Windows API, it allows very efficient mapping of memory to file data. Data is read from the file only when the program read the memory, the virtual memory pages don't take any space in the Windows paging file.

的确切相同的机制中,用于加载.NET组件。它是该文件提出的锁的存储器映射。这基本上是为什么当他们在.NET程序中使用组件被锁定。所述Image.Dispose()方法释放该锁。格斗锁通常表明你忘了你处理位图。很重要,忘记调用Dispose()不经常会给.NET类的问题,除了位图,因为它可以根据需要这么多的(托管)的内存。

The exact same mechanism is used to load .NET assemblies. It is the memory mapping that puts a lock on the file. Which is basically why assemblies are locked when they are used in a .NET program. The Image.Dispose() method releases the lock. Fighting the lock often indicates that you are forgetting to dispose your bitmaps. Very important, forgetting to call Dispose() doesn't often cause problems for .NET classes, except for Bitmap since it can need so much (unmanaged) memory.

是的,FromStream()$ P $作出这种优化pvents类。成本是显著,你会当位图被加载需要双倍的内存。这将是一个问题,当该位为大,你避开OOM当程序已经运行了一段时间(分段的地址空间),它不是在64位操作系统上运行。绝对避免这样做,如果该位图的宽度x高度x 4> = 45 MB,给予或采取。

Yes, FromStream() prevents the class from making this optimization. The cost is significant, you'll need double the memory when the bitmap is loaded. This will be a problem when the bitmap is large, you're skirting OOM when the program has been running for a while (fragmenting the address space) and its not running on a 64-bit operating system. Definitely avoid doing this if the bitmap's Width x Height x 4 >= 45 MB, give or take.

有些code,你不必跳通过CopyStream箍:

Some code, you don't have to jump through the CopyStream hoop:

    public static Image LoadImageNoLock(string path) {
        var ms = new MemoryStream(File.ReadAllBytes(path)); // Don't use using!!
        return Image.FromStream(ms);
    }

请注意,你不希望处置的MemoryStream,你会得到一个难以诊断一般错误时,位图被使用,如果你做的。由Image类懒读流引起的。

Note that you don't want to dispose the MemoryStream, you'll get a hard to diagnose "generic error" when the bitmap gets used if you do. Caused by the Image class lazy-reading the stream.