3

I am making a simple image viewer in WPF using FreeImage wrapper for .NET (http://freeimage.sourceforge.net/)

Here is the code

    public static void OpenImage(string path)
    {
        _rawImage = new FreeImageBitmap(path);
        BitmapSource bs = Utils.BitmapToBitmapSource(_rawImage.ToBitmap());
        mainWindow.imageComponent.Source = bs;
        mainWindow.imageComponent.Width = _rawImage.Width;
        mainWindow.imageComponent.Height = _rawImage.Height;

    }

    [System.Runtime.InteropServices.DllImport("gdi32")]
    static extern int DeleteObject(IntPtr o);

    public static BitmapSource BitmapToBitmapSource(System.Drawing.Bitmap source)
    {
        IntPtr ip = source.GetHbitmap();
        BitmapSource bs = null;
        try
        {
            bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip,
               IntPtr.Zero, Int32Rect.Empty,
               System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
        }
        finally
        {
            DeleteObject(ip);
        }

        return bs;
    }

The problem is ram spike and overall ram usage when displaying the image. The image I use for testing is a 5000x5000 jpeg. FreeImage reports it takes up 70mb of ram when in memory, which is correct. My app takes about 100mb(~30 for WPF and 70 for image) if I run only this part:

_rawImage = new FreeImageBitmap(path);

but when the full code is ran memory spikes to about 280mb which is way too much. In production code I can obviously dispose of all unused items but the initial spike is too much. I use IrfanView for image browsing and with same image it takes up a mere 77mb of memory.

I would like some solution(if there is one) to get rid of the spike it takes to load and convert the image into format that wpf Image can display. Maybe further reduce ram usage if possible. I work with big images and it's terrible if it will take 3x memory to load one image. I am rather new to WPF and this stuff overall so there might be something I'm missing.

If there is no possible solution in WPF, maybe something else? I am open for suggestions.

I tried searching but failed to find anything to solve my current problem.

Thanks a lot.

4

1 回答 1

1

这是我的看法:

<Window x:Class="LargeJpeg.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Image x:Name="Image" Stretch="None"/>
</Window>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var bitmap = new BitmapImage();
        bitmap.BeginInit();

        bitmap.CacheOption = BitmapCacheOption.None;
        bitmap.UriSource = new Uri(@"C:\5x5.jpg", UriKind.Absolute);
        bitmap.DecodePixelWidth = (int)Image.ActualWidth;
        bitmap.EndInit();
        bitmap.Freeze();


        Image.Source = bitmap;
    }
}

平均内存使用量:5000 x 5000 jpeg 上 130 mb。

于 2013-06-04T18:36:51.733 回答