Technorati Tags: wpfthumbnailsimageperformanceslowBitmapImage

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的更多相关文章

  1. jar命令使用介绍

    http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/jar.html Skip to Content Oracle Technol ...

  2. WPF实现炫酷Loading控件

    Win8系统的Loading效果还是很不错的,网上也有人用CSS3等技术实现,研究了一下,并打算用WPF自定义一个Loading控件实现类似的效果,并可以让用户对Loading的颗粒(Particle ...

  3. WPF loading遮罩层 LoadingMask

    原文:WPF loading遮罩层 LoadingMask 大家可能很纠结在异步query数据的时候想在wpf程序中显示一个loading的遮罩吧 今天就为大家介绍下遮罩的制作 源码下载 点击此处 先 ...

  4. WPF/SL: lazy loading TreeView

    Posted on January 25, 2012 by Matthieu MEZIL 01/26/2012: Code update Imagine the following scenario: ...

  5. 【WPF】BusyIndicator做Loading遮罩层

    百度了一下,粗略看了几个国内野人的做法,花了时间看下去感觉不太好用(比如有Loading居然只是作为窗体的一个局部控件的,没法全屏遮罩,那要你有何用?),于是谷歌找轮子去. 好用的轮子:http:// ...

  6. WPF动画 - Loading加载动画

    存在问题: 最近接手公司一个比较成熟的产品项目开发(WPF桌面端),其中,在登陆系统加载时,60张图片切换,实现loading闪烁加载,快有密集恐惧症了!!! 代码如下: private void L ...

  7. WPF 圆形Loading

    原文:WPF 圆形Loading 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a771948524/article/details/9271933 ...

  8. WPF loading加载动画库

    原文:WPF loading加载动画库 1. 下载Dll        https://pan.baidu.com/s/1wKgv5_Q8phWo5CrXWlB9dA 2.在项目中添加引用       ...

  9. WPF圆形环绕的Loading动画

    原文:WPF圆形环绕的Loading动画 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/ ...

随机推荐

  1. 文档 - STOMP Over WebSocket

    http://jmesnil.net/stomp-websocket/doc/ What is STOMP? STOMP is a simple text-orientated messaging p ...

  2. HTML5学习笔记(二十六):JavaScript的错误处理

    错误相关的调试和处理在开发中是特别重要的一种技能. try-catch 我们来看下面的情况: // noneFunc 这个方法并不存在 window.noneFunc(); // js 报错后终止运行 ...

  3. How lock works?

    Eliminating Synchronization-Related Atomic Operations with Biased Locking and Bulk Rebiasing http:// ...

  4. [Windows Azure] How to use the Windows Azure Blob Storage Service in .NET

    How to use the Windows Azure Blob Storage Service in .NET version 1.7 version 2.0 This guide will de ...

  5. 【Java】Java日志框架Logback的简单例子

    常用的日志框架 SLF4J,全称Simple Logging Facade for Java,即Java简单日志外观框架,顾名思义,它并非具体的日志实现,而是日志外观框架 java.util.logg ...

  6. convert2utf8withbom

    很久以前给同事要的转码bash 当时windows和mac总是出现中文注释乱码的情况,让人心塞的难过.又因为是老项目,现有源码太多了,不可能改模板重新创建.只能跑一遍这个玩意儿了…… #!/bin/b ...

  7. ubuntu mysql 远程连接问题解决方法

    在shell下输入mysql -uroot -p是可以登录的,所以问题应该是mysql不允许root用户远程登录的问题,于是通过输入下面命令: GRANT ALL PRIVILEGES ON *.*  ...

  8. vue的全局引用

    1 一般在vue中,有很多vue组件,这些组件每个都是一个文件.都可能需要引用到相同模块(或者插件).我们不想每个文件都import 一次模块. 如果是基于vue.js编写的插件我们可以用 Vue.u ...

  9. 【转】Pycharm创建py文件时自定义头部模板

    File->settings->Editor->File and Code Templates->Python Script #!/usr/bin/env python # - ...

  10. javascript检测浏览器的缩放状态实现代码 是指浏览器网页内容的百分比缩放(按Ctrl和+号键或者-号键的缩放)

    这里所说的缩放不是指浏览器大小的缩放,而是指浏览器网页内容的百分比缩放(按Ctrl和+号键或者-号键的缩放).检测这种缩放有很种方法,QQ空间都通过flash来检测浏览器是否处于缩放.这里提供java ...