Reputation: 6147
Is there a way in which I can improve the speed at which an insanely large image loads when placing it onto a canvas?
Is there a way I could use some sort of streaming method to load the image in chunks? Is there a way to stop the application from locking up when it's loading the image?
The image used for testing can be found here: http://www.finwe.mobi/orion360/test/equi/Orion360_test_image_8192x4096.jpg
The end result images will be larger than this.
Main.cs
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ImageBrush ib = new ImageBrush();
ib.ImageSource = new BitmapImage(new Uri(@"C:\Users\jmartini\Projects\wpf_image_streamer\testImage.png", UriKind.Relative));
//mycanvas.Background = ib;
canvas_view.Background = ib;
}
}
}
Main.XMAL
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Canvas Name="canvas_view"></Canvas>
</Grid>
</Window>
Upvotes: 0
Views: 261
Reputation: 3821
You'll need to load the image on a background thread to prevent your application from becoming unresponsive. You might consider displaying a lower-resolution version of the image at first so that the user has something to look at while the application loads the big version. You also need to consider displaying a progress bar, and which UI elements the user ought to be able to interact with while the image is still loading.
Although there are lots of things to consider when you start mixing asynchronous code with a user interface, the most basic use case is still relatively simple. The following example ought to get you started:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var brush = new ImageBrush(new BitmapImage(new Uri("thumbnail.jpg", UriKind.Relative)));
canvas_view.Background = brush;
this.Loaded += MainWindow_Loaded;
}
async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var bi = await LoadBigImage();
canvas.Background = new ImageBrush(bi);
}
async Task<BitmapImage> LoadBigImage()
{
var bi = new BitmapImage(new Uri("fullsize.jpg", UriKind.Relative));
bi.Freeze(); // note: must freeze DP objects when passing between threads
return bi;
}
}
Upvotes: 1