• 热门专题

System.Drawing.Bitmap要如何转换成WPF中可用的ImageSource呢?

作者:MakeIT  发布日期:2013-04-18 20:03:55
Tag标签:System  Drawing  Bitmap  WPF  
  • 在一般情况下,如果我们有一些图片需要显示在WPF的应用程序中,通常我们会使用Image,以及指定Image.Source属性,例如说下面这样

    img1.Source =
       new BitmapImage(new Uri(@"image file path", UriKind.RelativeOrAbsolute));

    利用这样的方式,将图片档案显示在Imagez上面;如果来源是byte array的话,会利用类似这样的方式


                System.IO.FileStream fs = 
                    new System.IO.FileStream(filepath, 
                        System.IO.FileMode.Open, System.IO.FileAccess.Read);
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                fs.Close();
                fs.Dispose();
    
                System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer);
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = ms;
                bitmapImage.EndInit();
                img1.Source = bitmapImage;

    这样就可以由byte数组转换成WPF中可以使用的图片来源了,不过上面这段程序代码有个问题需要处理,在memoryStream的部分,上面并没有看到Dispose的部分,这样子不会产生一些内存耗用的状况吗?于是尝试加上了MemortStream.Dispose的部分之后发现『疑?阿图片怎么显示不出来了』,这个部分请参考一下Convert memory stream to BitmapImage?

    必须要指定CacheOption的属性,强制在加载的时候去读取,才会确保显示的正常;不然如果需要加载的时候,memorystream已经被释放掉了,就会造成上面说的图片无法显示的状况了。稍加修改之后,程序代码会像是这样

     

    System.IO.FileStream fs = 
        new System.IO.FileStream(filepath, 
            System.IO.FileMode.Open, System.IO.FileAccess.Read);
    byte[] buffer = new byte[fs.Length];
    fs.Read(buffer, 0, buffer.Length);
    fs.Close();
    fs.Dispose();
    
    System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer);
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.BeginInit();
    bitmapImage.StreamSource = ms;
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    bitmapImage.EndInit();
    ms.Dispose();
    img1.Source = bitmapImage;

    好,看完了一般情况的使用之后,来看一下System.Drawing.Bitmap的部分;会甚么会有这个需求呢?假设今天你呼叫的是第三方厂商提供的dll,dll回传的就已经是System.Drawing.Bitmap的话,就会遇到需要转换的状况了。那么应该怎么转换呢?下面列出两种方式作为参考 www.it165.net

    利用上面提到的方式,将Bitmap储存成memorystream之后,指定给BitmapImage


            private BitmapImage BitmapToBitmapImage(System.Drawing.Bitmap bitmap)
            {
                BitmapImage bitmapImage = new BitmapImage();
    
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    bitmap.Save(ms, bitmap.RawFormat);
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = ms;
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();
                    bitmapImage.Freeze();
                }
                
                return bitmapImage;
            }
    

    利用System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap方式来做转换

     

            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern bool DeleteObject(IntPtr hObject);
    
            private BitmapSource BitmapToBitmapSource(System.Drawing.Bitmap bitmap)
            {
                IntPtr ptr = bitmap.GetHbitmap();
                BitmapSource result =
                    System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                        ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                //release resource
                DeleteObject(ptr);
    
                return result;
            }

    这边要请特别注意一下,在最后一定要呼叫DeleteObject来做资源的释放(可以参考MSDN的这篇文章),不然内存是会越吃越凶的

     

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规