Speeding up image loading in WPF using thumbnails
Technorati Tags: wpf, thumbnails, image, performance, slow, BitmapImage
During a recent WPF session I needed to build a ListBox that showed a bunch of images loaded from an arbitrary directory. Thanks to WPF's data binding, this was trivial - I just needed to get a collection of objects that each had a property pointing to the full path of the image, and WPF would take care of all the loading/displaying. Something like this:
1: <ListView ItemsSource="{Binding}">
2: <ListView.ItemTemplate>
3: <DataTemplate>
4: <Image Source="{Binding Path=FullPath}" />
5: </DataTemplate>
6: </ListView.ItemTemplate>
7: </ListView>
The assumption here is that the DataContext for this window is set to a collection of "Photo" objects. The Photo class has a member called "FullPath" which is just a string with the full path of the photo on disk - this is what the Image.Source member expects.
This worked, but it didn't take long to see a major issue: With today's cameras, loading multiple 5+ megapixel images could take a while (not to mention the RAM requirements).
After a little digging, I found a solution. There exists a feature in the BitmapImage class that allows you to load an image but tell it to only load a thumbnail. To use this, you have to step out of the shrink-wrapped data binding world and insert a converter into the equation. Basically, this converter will take the above string with the full image path, it will load the image (as a thumbnail), and pass it back into the Image.Source parameter as aBitmapImage, which it's happy to consume.
First, let's look at this converter's code and how it loads the thumbnail:
1: public class UriToBitmapConverter : IValueConverter
2: {
3: public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
4: {
5: BitmapImage bi = new BitmapImage();
6: bi.BeginInit();
7: bi.DecodePixelWidth = 100;
8: bi.CacheOption = BitmapCacheOption.OnLoad;
9: bi.UriSource = new Uri( value.ToString() );
10: bi.EndInit();
11: return bi;
12: }
13:
14: public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
15: {
16: throw new Exception("The method or operation is not implemented.");
17: }
18: }
Notice line #7. That's the magic line which tells it how big of a thumbnail to load. The smaller the number, the quicker the load, the lower the quality. Notice also line #8 - this is there to force the image file to be closed after it's loaded. Without that, I found that my app couldn't write back to the image file since the ListBox still had it open.
Next, let's look at the XAML change to insert this converter into the mix. You'll need to create a resource for it:
1: <Window.Resources>
2: <local:UriToBitmapConverter x:Key="UriToBitmapConverter" />
3: </Window.Resources>
The "local:" namespace directive on line #2 is one I'd made sure to add to my main "Window" declaration, like this (line #4):
1: <Window x:Class="MyClass.Demo"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:local="clr-namespace:MyClass"
5: Title="Demo" Height="300" Width="300">
Lastly, use this new resource in the Image element so that FullPath (a string) gets pushed through the converter before Image.Source gets it:
1: <Image Source="{Binding Path=FullPath, Converter={StaticResource UriToBitmapConverter}}" />
That's it. Your images will now load very quickly. Tweak the thumbnail size to vary the speed versus quality.
Avi
Speeding up image loading in WPF using thumbnails的更多相关文章
- jar命令使用介绍
http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/jar.html Skip to Content Oracle Technol ...
- WPF实现炫酷Loading控件
Win8系统的Loading效果还是很不错的,网上也有人用CSS3等技术实现,研究了一下,并打算用WPF自定义一个Loading控件实现类似的效果,并可以让用户对Loading的颗粒(Particle ...
- WPF loading遮罩层 LoadingMask
原文:WPF loading遮罩层 LoadingMask 大家可能很纠结在异步query数据的时候想在wpf程序中显示一个loading的遮罩吧 今天就为大家介绍下遮罩的制作 源码下载 点击此处 先 ...
- WPF/SL: lazy loading TreeView
Posted on January 25, 2012 by Matthieu MEZIL 01/26/2012: Code update Imagine the following scenario: ...
- 【WPF】BusyIndicator做Loading遮罩层
百度了一下,粗略看了几个国内野人的做法,花了时间看下去感觉不太好用(比如有Loading居然只是作为窗体的一个局部控件的,没法全屏遮罩,那要你有何用?),于是谷歌找轮子去. 好用的轮子:http:// ...
- WPF动画 - Loading加载动画
存在问题: 最近接手公司一个比较成熟的产品项目开发(WPF桌面端),其中,在登陆系统加载时,60张图片切换,实现loading闪烁加载,快有密集恐惧症了!!! 代码如下: private void L ...
- WPF 圆形Loading
原文:WPF 圆形Loading 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a771948524/article/details/9271933 ...
- WPF loading加载动画库
原文:WPF loading加载动画库 1. 下载Dll https://pan.baidu.com/s/1wKgv5_Q8phWo5CrXWlB9dA 2.在项目中添加引用 ...
- WPF圆形环绕的Loading动画
原文:WPF圆形环绕的Loading动画 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/ ...
随机推荐
- Ubuntu 18.04 安装和常用软件安装
Ubuntu 18.04 安装 下载 Ubuntu 制作 U 盘启动盘 设置电脑为 U 盘启动 插入 U 盘,重启电脑 按照提示安装 Ubuntu 更新 NVIDIA 显卡和 Broadcom 无线网 ...
- jqgrid 设置为每行单选
jqgrid 不支持单选,自己自带了多选multiselect 那么单选怎么做呢,可以参考如下配置 multiselect: true, multiboxonly:true, gridComplete ...
- WCF - 服务实例管理模式
WCF 提供了三种实例上下文模式:PreCall.PreSession 以及 Single.开发人员通过 ServiceBehavior.InstanceContextMode 就可以很容易地控制服务 ...
- java 字符串格式化
转:http://blog.sina.com.cn/s/blog_af26e3330101988v.html 1.对整数进行格式化:%[index$][标识][最小宽度]转换方式 我们可以看到,格式化 ...
- Hive怎样加入第三方JAR
以增加elsaticsearch-hadoop-2.1.2.jar为例,讲述在Hive中增加第三方jar的几种方式. 1,在hive shell中增加 [hadoop@hadoopcluster78 ...
- class() 高级用法 -- lua
class() 高级用法 class() 除了定义纯 Lua 类之外,还可以从 C++ 对象继承类. 比如需要创建一个工具栏,并在添加按钮时自动排列已有的按钮,那么我们可以使用如下的代码: -- 从 ...
- Spark SQL inferSchema实现原理探微(Python)【转】
使用Spark SQL的基础是“注册”(Register)若干表,表的一个重要组成部分就是模式,Spark SQL提供两种选项供用户选择: (1)applySchema applySche ...
- 网易云信消息抄送服务的第三方接口示例(Java)
package com.netease.nim.route; import com.alibaba.fastjson.JSONObject; import com.netease.nim.route. ...
- c++11支持类数据成员的初始化
在阅读TCPL第四版的时候看到,c++11支持类数据成员的初始化(In-Class Initializer),很有意思的功能. 测试代码如下: class Date { int year{2015}; ...
- Spring Batch并行与扩展
1. 概述 Spring Batch提供了多种方式用于处理并行,提高性能.主要分为2大类: - 单个进程,多线程 - 多个进程 因此,可以细分为以下几类: - 多线程Step(Multi-thread ...