wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html

如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包含图像头等信息)快速显示到界面,那么你来对地方了,看完这篇博客会解决困扰了你一天,或者一个礼拜,或者一年,或者一辈子的问题,时间的长短取决于你看到这篇博客的时间。

请注意:如果本篇博客对于解决你的问题起到了决定性的作用,那么请在你的代码里加上以下两行内容,请尊重别人的努力。转载请注明出处

// provide by zhangshaohui

// 本文网址

以下是正文:

在你寻找解决方案的过程中,一定看到过这样的代码:

1、这个代码最常见,网上到处都是,的确可以用,也简单清晰,但是速度太慢,显示一个3000*3000的大概要40ms,我跟踪了一下代码,主要是new stream,以及EndInit比较耗时,但是用这个方法又绕不过去这两行代码。

复制代码
  public BitmapImage BitmapToBitmapImage(Bitmap bitmap)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Png); 
                stream.Position = 0;
                BitmapImage result = new BitmapImage();
                result.BeginInit();
                result.CacheOption = BitmapCacheOption.OnLoad;
                result.StreamSource = stream;
                result.EndInit();
                result.Freeze();
                return result;
            }
           
        }

2、这个也是常见的办法,好像还是msdn上推荐的,缺点是更慢

|-------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public static ImageSource ChangeBitmapToImageSource(Bitmap bitmap) ``{ ``IntPtr hBitmap = bitmap.GetHbitmap(); ``ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( ``hBitmap, ``IntPtr.Zero, ``Int32Rect.Empty, ``BitmapSizeOptions.FromEmptyOptions()); ``if (!APIConverter.DeleteObject(hBitmap)) ``{ ``throw new System.ComponentModel.Win32Exception(); ``} ``return wpfBitmap; ``} |

如果对于显示速度没有什么要求,那么这两个办法还是可以用用的,但是如果对于性能有要求,而且又数据量很大,比如接收超高清的视频数据,那么这两个方法是完全满足不了需求的。

本文的方案是:

1、以显示3000 * 3000的图像为例,下面的代码是伪代码

2、定义ImageSource ImgSource,ImgSource绑定到image控件的Source属性

3、PixelFormats.Gray16,定义为PixelFormats.Gray8也是可以的,不过就需要在WriteableBitmap构造函数最后一个参数添加伪彩表,当然还可定义rgb的格式,这个看裸数据的格式以及需求来了,这里只是抛砖引玉,方法是通用的。

4、本方案的优点是没有频繁的内存分配和释放,既节省时间,又不用担心内存溢出,想更新哪里更新哪里,代码简单易懂,速度极快

复制代码
ViewModel中
 public class MainWindowViewModel : ViewModelBase
    {
        private WriteableBitmap _wbBitmap;

        public MainWindowViewModel()
        {
        _wbBitmap = new WriteableBitmap(3000, 3000, 96, 96, PixelFormats.Gray16, null);
            ImgSource = _wbBitmap;
        }    
        public void ShowImage(short[] rawData)// rawData是存储图像裸数据的buffer
        {
         unsafe
            {
                _wbBitmap.Lock();
                Marshal.Copy(rawData,0,_wbBitmap.BackBuffer,3000*3000); //请注意_wbBitmap的数据格式以及buffer大小,以免溢出和显示异常
复制代码
_wbBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, 3000, 3000)); _wbBitmap.Unlock(); } } } 
相关推荐
周杰伦fans3 小时前
C# 23种设计模式详解与示例
开发语言·设计模式·c#
xb11324 小时前
C#——方法的定义、调用与调试
开发语言·c#
code bean5 小时前
【C#】以 BlockingCollection 为核心的多相机 YOLO 检测任务处理框架
c#
时光追逐者6 小时前
一款专门为 WPF 打造的开源 Office 风格用户界面控件库
ui·开源·c#·.net·wpf
-可乐加冰吗9 小时前
SuperMap iObjects .NET 11i 二次开发(十五)—— 类型转换之面转点
visualstudio·c#·.net
ajassi20009 小时前
开源 C# 快速开发(十二)进程监控
开发语言·开源·c#
大飞pkz11 小时前
【设计模式】代理模式
开发语言·设计模式·c#·代理模式
sali-tec12 小时前
C# 基于halcon的视觉工作流-章40-OCR训练识别
开发语言·图像处理·算法·计算机视觉·c#·ocr
该用户已不存在14 小时前
.NET语言大舞台,有才你就来
c#·.net
浅笑离愁123415 小时前
物联网智能安防系统
stm32·物联网·c#