不管什么东西,但凡太大了,总是让人又爱又恨啊!(很有道理的样子,大家鼓掌└( ̄  ̄└)(┘ ̄  ̄)┘)

猿:老板,现在这社会啊,真是浮躁啊,之前还是什么1080P,然后就到了2K,现在又到了4K……他们是想把毛孔都看清楚?

老板:能不能做?

猿:已经做好了啊,但是……反正这次我们能说会道的X经理也没能忽……说服客户。

老板:是什么问题嘛,说出来我帮你想想办法。(老板真是好人啊,语重心长)

猿(ノへ ̄、):客户不是升级了4K摄像机吗,哎哟,那玩意儿,老长了,就跟火箭筒似的,扛起来那感觉(ง •̀_•́)ง,真是拉风……

老板:咳咳……

猿:嗯,4K,拍出来的照片分辨率4096x2160,一张图片就有30多M,然后……我们的程序挂了,内存崩了。╮( ̄▽ ̄")╭

老板:嗯,这个问题嘛……

猿:昨晚我加班到凌晨三点,各种调试,各种查资料,终于搞定了,今天早上让小X过去更换了,然后……

老板:辛苦了,办公室里有吃的,晚上加班尽管吃!

猿:( ̄▽ ̄")……

猿:然后内存是没爆了,但是大图出来的使用有2~3秒的空白……也不能操作……X经理正在给我们争取时间……

老板:这样啊,我给你一个我朋友的电话,他也是搞软件的,很牛X的……

嗯,各位童鞋,看到这里就应该明白,对话已经结束。这就开始我们的代码……

XAML我们就简单点:用ListView做个列表,一个用于显示大图的Image,一个遮罩层Border

  <Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="420"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="lvImages" ScrollViewer.CanContentScroll="False" SelectionChanged="lvImages_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Converter={StaticResource ImageSourceConverter}, Mode=OneTime,ConverterParameter=400}" Width="400" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ScrollViewer Grid.Column="1" >
<ScrollViewer.Background>
<ImageBrush ImageSource="{Binding SelectedItem, ElementName=lvImages,Converter={StaticResource ImageSourceConverter}}" Stretch="Uniform"/>
</ScrollViewer.Background>
<Image Name="bigImage" MouseWheel="bigImage_MouseWheel" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<ScaleTransform x:Name="scale"/>
</Image.RenderTransform>
</Image>
</ScrollViewer>
<Border Name="conver" Background="#60000000" Visibility="Hidden" Grid.ColumnSpan="2">
<Path Data="M30.330999,48.228C31.299783,48.422099 32.299767,48.531501 33.330949,48.531501 34.360932,48.531501 35.363415,48.422099 36.335999,48.228L36.335999,66.659003 30.330999,66.659003z M43.268281,44.750998L52.394999,60.832034 47.175917,63.796996 38.038999,47.713359C39.994767,47.070048,41.753928,46.067427,43.268281,44.750998z M23.209264,44.598998C24.700174,45.940215,26.447487,46.971526,28.389,47.638133L19.002135,63.568 13.824999,60.518466z M47.700966,38.078002L63.757998,47.260428 60.782928,52.473998 44.726998,43.300773C46.044784,41.78905,47.055174,40.028529,47.700966,38.078002z M18.923298,37.936999C19.546999,39.89281,20.5418,41.665007,21.844,43.188594L5.7032509,52.206 2.7709999,46.960906z M18.4298,30.342997C18.240998,31.305102 18.131697,32.306304 18.131697,33.328299 18.131697,34.360797 18.237098,35.373698 18.435,36.3502L0.0077514648,36.370997 0,30.365096z M66.659098,30.285998L66.666998,36.294497 48.231798,36.313998C48.4272,35.347804 48.531301,34.352805 48.531301,33.328002 48.531301,32.294097 48.4272,31.284898 48.227999,30.308202z M60.963728,14.451999L63.895998,19.696799 47.743868,28.718999C47.120075,26.764499,46.123985,24.996299,44.817999,23.474099z M5.8831024,14.181999L21.936999,23.357735C20.616765,24.868125,19.607615,26.627213,18.960647,28.578999L2.9039993,19.403264z M47.663984,3.0889991L52.839998,6.1383522 43.456712,22.064999C41.96595,20.723838,40.213178,19.687466,38.276999,19.020785z M19.487081,2.8649989L28.617,18.94893C26.66778,19.585601,24.902254,20.590758,23.394619,21.910998L14.261999,5.8297189z M30.330999,0L36.335999,0 36.335999,18.430999C35.363416,18.2357 34.36093,18.127599 33.330949,18.127599 32.299765,18.127599 31.299782,18.2357 30.330999,18.430999z"
Stretch="Uniform" Margin="200" Fill="Red" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<RotateTransform x:Name="rotate" Angle="0"/>
</Path.RenderTransform>
</Path>
</Border>
</Grid>

后台代码:

 private void Window_Loaded(object sender, RoutedEventArgs e)
{
//高清大图,你懂的。
var path = Combine(AppDomain.CurrentDomain.BaseDirectory, "images");//using static System.IO.Path;
var files = Directory.GetFiles(path);
lvImages.ItemsSource = files;
} private async void lvImages_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//在选中项更改时进行处理,
if (lvImages.SelectedIndex > -)
{
//选中的项
var current = e.AddedItems[]; bigImage.Source = null; //坐和放宽,很快就好。
conver.Visibility = Visibility.Visible;
rotate.BeginAnimation(RotateTransform.AngleProperty, new DoubleAnimation(, TimeSpan.FromMilliseconds())
{ RepeatBehavior = RepeatBehavior.Forever }); //await一下
try
{
var source = await Task.Run<ImageSource>(() =>
{
var p = current.ToString();
var s = new BitmapImage();
s.BeginInit();
s.CacheOption = BitmapCacheOption.OnLoad;
//打开文件流
using (var stream = File.OpenRead(p))
{
s.StreamSource = stream;
s.EndInit();
//这一句很重要,少了UI线程就不认了。
s.Freeze();
}
return s;
});
//出炉
bigImage.Source = source;
}
catch { }
//好了,不用转了
rotate.BeginAnimation(RotateTransform.AngleProperty, null);
conver.Visibility = Visibility.Hidden;
}
else
{
var s = bigImage.Source;
s = null;
bigImage.Source = null;
}
} private void bigImage_MouseWheel(object sender, MouseWheelEventArgs e)
{
//高清大图嘛,当然要放大了仔细看看
var d = e.Delta / 1000.0;
if (scale.ScaleX + d < )
{
scale.ScaleX = scale.ScaleY = ;
return;
}
scale.ScaleX += d;
scale.ScaleY += d;
}

一个简单的ImageSourceConverter:

  public class ImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return value;
var source = new BitmapImage();
source.BeginInit();
source.UriSource = new Uri(value.ToString(), UriKind.Absolute);
//设置解码的分辨率大小,也就是搞个缩略图
source.DecodePixelWidth = parameter != null ? int.Parse(parameter.ToString()) : ;
source.EndInit();
return source; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

看图:

WPF 异步加载高清大图的更多相关文章

  1. IOS 多个UIImageView 加载高清大图时内存管理

    IOS 多个UIImageView 加载高清大图时内存管理 时间:2014-08-27 10:47  浏览:59人 当我们在某一个View多个UIImageView,且UIImageView都显示的是 ...

  2. 关于SDWebImage加载高清图片导致app崩溃的问题

    链接是对于SDWebImage的使用方法 http://www.cnblogs.com/JimmyBright/p/4457258.html 使用SDWebImage加载高清图片的时候,往往会报内存溢 ...

  3. 【.net深呼吸】WPF异步加载大批量图像

    如何在WPF中加载大批量数据,并且不会阻塞UI线程,尤其是加载大量图片时,这活儿一直是很多朋友都相当关注的.世上没有最完美的解决之道,咱们但求相对较优的方案. 经过一些试验和对比,老周找到了一种算是不 ...

  4. WPF 异步加载窗体

    加载某个界面时,需要获取数据,而数据返回的时间比较长,这个时候可以异步加载界面. 1.在该窗体的加载事件(Load)中编写以下代码: new Thread(p=>{DataBinding();} ...

  5. wpf 异步加载 只需6段代码

    private BackgroundWorker worker = null; ProgressBar probar = new ProgressBar(); private int percentV ...

  6. WPF 多线程 UI:设计一个异步加载 UI 的容器

    对于 WPF 程序,如果你有某一个 UI 控件非常复杂,很有可能会卡住主 UI,给用户软件很卡的感受.但如果此时能有一个加载动画,那么就不会感受到那么卡顿了.UI 的卡住不同于 IO 操作或者密集的 ...

  7. Android引入高速缓存的异步加载全分辨率

    Android引进高速缓存的异步加载全分辨率 为什么要缓存 通过图像缩放,我们这样做是对的异步加载优化的大图,但现在的App这不仅是一款高清大图.图.动不动就是图文混排.以图代文,假设这些图片都载入到 ...

  8. [翻译]Bitmap的异步加载和缓存

    内容概述 [翻译]开发文档:android Bitmap的高效使用 本文内容来自开发文档"Traning > Displaying Bitmaps Efficiently", ...

  9. WPF技术触屏上的应用系列(五): 图片列表异步加载、手指进行缩小、放大、拖动 、惯性滑入滑出等效果

    原文:WPF技术触屏上的应用系列(五): 图片列表异步加载.手指进行缩小.放大.拖动 .惯性滑入滑出等效果 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统, ...

随机推荐

  1. JavaScript(五)——插入地图

    代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. ...

  2. 【JSP】JSP基础学习记录(二)—— JSP的7个动作指令

    2.JSP的7个动作指令: 动作指令与编译指令不同,编译指令是通知Servlet引擎的处理消息,而动作指令只是运行时的动作.编译指令在将JSP编译成Servlet时起作用:而处理指令通常可替换成JSP ...

  3. Bootstrap入门(二)栅格

    Bootstrap入门(二)栅格 Bootstrap入门(二)栅格 全局CSS样式--栅格 先引入本地的CSS文件(根据自己的文件夹,有不同的引入地址,我是放在一个新建的名为css的文件夹中) con ...

  4. 给锁住的行解锁(oracle)

    1.查看数据库锁,诊断锁的来源及类型: select object_id,session_id,locked_mode from v$locked_object; 或者用以下命令: select b. ...

  5. Spring mvc框架 controller间跳转 ,重定向 ,传参

     一.需求背景     1. 需求:spring MVC框架controller间跳转,需重定向.有几种情况:不带参数跳转,带参数拼接url形式跳转,带参数不拼接参数跳转,页面也能显示.   @Req ...

  6. ubuntu下eclipse scala开发插件(Scala IDE for Eclipse)安装

    1. 环境介绍 系统:ubuntu16.04(不过和系统版本关系不大) elipse:Neon.1aRelease (4.6.1) 2. 插件介绍 Scala IDE for eclipse是elip ...

  7. 05章 OGNL

    一.OGNL全称是Object Graph Navigation Language,即对象导航图语言 OGNL在框架中主要做两件事情:表达式语言和类型转换器 OGNL在框架中的作用以及数据的流入流出: ...

  8. JavaScript作用域闭包简述

    JavaScript作用域闭包简述 作用域 技术一般水平有限,有什么错的地方,望大家指正. 作用域就是变量起作用的范围.作用域包括全局作用域,函数作用域以块级作用域,ES6中的let和const可以形 ...

  9. string、math类、random随机数、datetime、异常保护

    今天讲的知识点比较多,比较杂,以至于现在脑子里还有点乱,慢慢来吧... string (1)string.length; (获得你string字符串的长度) (2)a = a.Trim(); 重新赋值 ...

  10. S2结业考试的第一次测验

    错题分析: 1:java中的错误处理是通过异常处理模型来实现的,那么异常处理模块能处理的错误是: A:运行时错误 B:逻辑错误 C:语法错误 D:内部错误 正确答案是:A 解析:运行时异常都是Runt ...