如何更有效地在RichTextBox中加载图像?

4

我正在将一张大图片(95729 kb)拖放到我的 RichTextBox 中,但内存使用量非常难以理解:memory usage 为什么它会占用超过700 MB的空间?

我的拖放代码:

private void RtbEditor_PreviewDrop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        if (files != null && files.Length > 0)
        {
            foreach (var file in files)
            {
                // Filter out non-image files.
                if (IsValidImageFile(file))
                {
                    BitmapImage bitmap = new BitmapImage();
                    bitmap.BeginInit();            
                    bitmap.UriSource = new Uri(file, UriKind.Absolute);            
                    bitmap.EndInit();
                    Image image = new Image();            
                    image.Source = bitmap;            
                    var container = new InlineUIContainer(image, rtbEditor.CaretPosition);
                    rtbEditor.CaretPosition = container.ElementEnd;
                }
            }
        }
    }
}

对于图像检查,我只使用了图像头:仅检查头部。 我做错了什么?

2个回答

4
这张图片可能具有巨大的分辨率,并使用PNG或JPEG等格式进行压缩,以使最终文件大小更小。但是,为了呈现图像,渲染器需要将图像解压缩为具有(A)RGB值的实际像素。
一个未压缩的3000x3000像素、每像素32位的图像大小约为36 MB。因此,您的图像必须更大。
无论如何,为什么要在文本框中呈现这样一个大图像呢?

说实话,在大多数情况下并不需要。但是我不明白为什么加载只有 ~100 mb 的 jpeg 图像时会占用如此多的内存。我想让 RichTextBox 像 Microsoft Word 一样工作。也许我很蠢:) 对我的英语表示抱歉。 - Roman
一个100 MB的JPEG文件非常大。如果你想让用户能够将图片拖入你的文本编辑器中,你需要将图片大小调整为更易处理的尺寸。 - CodeCaster

1
你肯定不需要那么多像素。只需在 BitmapImage.BeginInit()BitmapImage.EndInit() 之间设置 BitmapImage.DecodePixelHeightBitmapImage.DecodePixelWidth 到适当的值即可。除非你不关心原始宽高比,否则不要同时设置两者。

我知道我不需要那么多像素。但是我想要实现图像调整大小的功能。在BitmapImage.DecorePixehHeight之后,图像质量会降低,对吗?你知道为什么它占用了这么多内存吗? - Roman
@Roman 正如你所说,你加载了一个100MB的jpeg图片,它将在内存中解码为RGBA图像。那么,你还能期望什么? - Alex.Wei
这意味着我不明白发生了什么。所以,当我加载100 MB的JPEG时,它将被解码为RGBA,这比JPEG更大?抱歉,但我不擅长图像格式化。 - Roman
@Roman Ok... 实际上,在 EndInit() 之后,您可以使用 Height * Width * Format.BitsPerPixel / 8 来计算解码图像占用的字节数。或者您也可以通过 BitmapImage._finalSource.DUCECompatiblePtr._gcPressure._gcPressure 来查看它从 GC 中保留了多少内存。 - Alex.Wei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接