




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
方案1.WPF异步加载BitmapImage当你在WPF主线程中时不时需要加载图片时,界面上的Animation会因为IO操作而卡壳,要想保持动画的流畅就必须将IO操作放到后台线程中操作,如下:private void ChangeImage() Image image = new Image(); new Thread(new ThreadStart() = BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.UriSource = new Uri(imagesindex+ % images.Count); bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); Dispatcher.BeginInvoke(Action)() = image.Source = bitmap; image.Stretch = Stretch.UniformToFill; TransitionBox.Content = image; ); ).Start();方案2.WPF中加载高分辨率图片性能优化 在最近的项目中,遇到一个关于WPF中同时加载多张图片时,内存占用非常高的问题。问题背景: 在一个ListView中同时加载多张图片,注意:我们需要加载的图片分辨率非常高。代码XAML: C#:public partial class MainWindow : Window public MainWindow() InitializeComponent(); private void Button_Click(object sender, RoutedEventArgs e) lvImages.Items.Clear(); / Image folder location: D:Pics string files = System.IO.Directory.GetFiles(D:Pics); List models = new List(); foreach(var path in files) BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new System.Uri(path); image.EndInit(); image.Freeze(); models.Add(new ImageSourceModel() ImageSource = image ); lvImages.ItemsSource = models; public class ImageSourceModel public ImageSource ImageSource get; set; 优化方案:(1). 初始加载时,只加载部分图片并显示。当ScrollViewer滚动到底部时,再加载一部分。关于这个方案,可以参考 WPF MVVM模式下实现ListView下拉显示更多内容;但是这并不能解决最终内存占用过高的情况。(2). 给图片设置DecodePixelWidth属性,BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new System.Uri(path); image.DecodePixelWidth = 800; image.EndInit(); image.Freeze();models.Add(new ImageSourceModel() ImageSource = image );方案3.wpf大图片处理速度优化:指针操作,并行操作,几十倍优化(1)标准的int30数组遍历计算 release 0.28sunsafe public static void TestGray1(this WriteableBitmap bmp) using (var context = bmp.GetBitmapContext() int height = context.Height; int width = context.Width; for (int y = 0; y height; y+) for (int x = 0; x 16); var g = (byte)(c 8); var b = (byte)(c); var gray = (r * 38 + g * 75 + b * 15) 7); var color=(255 24) | (gray 16) | (gray 8) | gray; context.Pixelspos=color; (2)标准的int32指针遍历计算 release 0.04sunsafe public static void TestGray2(this WriteableBitmap bmp) using (var context = bmp.GetBitmapContext() var ptr = context.Pixels; int height = context.Height; int width = context.Width; for (int y = 0; y height; y+) for (int x = 0; x 16) ; var g = (byte)(c 8) ; var b = (byte)(c) ; var gray = (r * 38 + g * 75 + b * 15) 7); var color = (255 24) | (gray 16) | (gray 8) | gray; *ptr = color; ptr+; (3)colorstruct指针 便利计算 0.02sStructLayout(LayoutKind.Sequential)public struct PixelColor public byte Blue; public byte Green; public byte Red; public byte Alpha; unsafe public static void TestGray3(this WriteableBitmap bmp) using (var context = bmp.GetBitmapContext() var ptr = (PixelColor*)context.Pixels; int height = context.Height; int width = context.Width; for (int y = 0; y height; y+) for (int x = 0; x 7); (*ptr).Green=(*ptr).Red=(*ptr).Blue = (byte)gray; ptr+; (4)作为对比,我又测试了一下 GDI+的 指针处理图片的速度 0.06spublic static unsafe Bitmap ToGray(Bitmap img) var rect = new System.Drawing.Rectangle(0, 0, img.Width, img.Height); var data = img.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var ptr = (ColorType*)data.Scan0.ToPointer(); var bytes = new Int32img.Width * img.Height; var height = img.Height; var width = img.Width; for (int y = 0; y height; y+) for (int x = 0; x 7); (*ptr).R = (*ptr).G = (*ptr).B = (byte)gray; ptr+; img.UnlockBits(data); return img;(5)重头戏来了。我一直对Parallel.For 很迷惑,为什么他的消耗时间是普通for的好几倍。今天仔细研究了一下,发现原来是用错了 0.01s release 笔记本i5cpu,如果台式机的I7会更加强悍,速度会成半成半降低。 主要是利用了微软的任务并行库的循环并行化的方法。 注意:默认的并行循环对于函数体很小的情况是很慢的,这种情况必须用Partitioner 创建循环体,这在MSDN有介绍,是关键之中的关键unsafe public static void TestGray5(this WriteableBitmap bmp) using (var context = bmp.GetBitmapContext() int height = context.Height; int width = context.Width; Parallel.ForEach(Partitioner.Create(0, height), (h) = var ptr = (PixelColor*)context.Pixels; ptr += h.Item1 * width; for (int y = h.Item1; y h.Item2; y+) for (int x = 0; x 7); (*ptr).Green = (*ptr).Red = (*ptr).Blue = (byte)gray; ptr+; ); 感想:1.绝对不要在循环体内使用属性或函数,很有可能会降低数倍计算速度。因为属性本质上是个函数,而在循环体内最好不要再调用函数,如果确实需要用内联代码的方式,c#没有inline,那么copy代码吧,反正为了速度。2. 用指针移位操作 似乎比 直接数组访问要快10倍啊,我感觉要么是cache命中的原因,要么是 数组本身存取被属性封装了。相当于又调用了函数。3.TPL 任务并行库果真好用,看来微软早已考虑过大量数据并行的循环优化问题09年,只是我一直用错了方法,才觉得很慢。方案4. WPF ListBox异步加载图片ListBox加载大量图片时,如果采用同步方法,页面出来速度太慢,最好办法就是采用异步加载了,直接上代码,如下:前台页面完整代码: 后台代码:public partial class MainWindow : Window public MainWindow() InitializeComponent(); private void Window_Loaded(object sender, RoutedEventArgs e) foreach (string file in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory+Photo) string file1 = file;/必须有,不妨试试不加这段代码,看看效果就明白了 Dispatcher.BeginInvoke(Action)() = BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.UriSource = new Uri(file1,UriKind.RelativeOrAbsolute); bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); double ww = bitmap.PixelWidth; double hh = bitmap.PixelHeight; Image image = new Image(); image.Source = bitmap; image.Height = 200; image.Width = 200 * (ww / hh); this.list.Items.Add(image); ); 这样的方法页面出来速度是快了,但图片加载速度还是慢,原本预想结果是图片是一张一张加在进来的,却图片是全部一下加载到界面上,所以速度显得有点慢。解决办法采用Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)() =.方案5. 控制台异步加载程序 (WPF)private void ChangeImage()Image image = new Image();new Thread(new ThreadStart() = BitmapImage bitmap = new BitmapImage();bitm
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025内蒙古工业大学招聘20名博士学位事业编制工作人员模拟试卷及答案详解(有一套)
- 2025年中学音乐考试试题及答案
- 区域地理亚洲试卷及答案
- 2025黑龙江哈尔滨“丁香人才周”(春季)事业单位引才招聘考前自测高频考点模拟试题及答案详解一套
- 2025北京第四实验学校招聘45人考前自测高频考点模拟试题及答案详解(历年真题)
- 2025年新能源行业绿色制造技术创新与新能源创新报告
- 电商知识产权治理:2025年平台知识产权保护与知识产权保护与知识产权风险防控报告
- 金融反欺诈2025年大数据分析在风险防范中的应用案例报告
- 2025年汉中市中医医院招聘见习人员(24人)考前自测高频考点模拟试题及答案详解(夺冠)
- 2025-2030工业软件市场需求与未来发展预测报告
- 国家机关事业单位工作人员受到行政刑事处罚工资处理意见
- 道路运输管理机构人员编制理论研究
- 垃圾发电厂考试题库含答案全套
- 仁爱版九年级英语上册unit2topic1复习课市公开课一等奖省课获奖课件
- 北京市国内旅游合同书
- 公司品牌建设五年规划
- 第二单元 三国两晋南北朝的民族交融与隋唐统一多民族封建国家的发展 知识清单 高中历史统编版(2019)必修中外历史纲要上册
- 居室环境的清洁与消毒
- GB/T 39766-2021人类生物样本库管理规范
- GB/T 2900.50-2008电工术语发电、输电及配电通用术语
- GB/T 2518-2008连续热镀锌钢板及钢带
评论
0/150
提交评论