Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 内存图像显示_.net_Wpf_Image_Data Binding - Fatal编程技术网

.net 内存图像显示

.net 内存图像显示,.net,wpf,image,data-binding,.net,Wpf,Image,Data Binding,我试图为我的列表视图构建一个项目模板,并且我绑定到一个实体列表。我拥有的实体有一个系统.Drawing.Image,我想显示它,但到目前为止,我还无法确定如何将其绑定到块 我在互联网上找到的每一个示例和文档都与可通过uri访问的图像有关,即硬盘或网站上的文件 <DataTemplate x:Key="LogoPreviewItem"> <Border BorderBrush="Black" BorderThickness="1">

我试图为我的列表视图构建一个项目模板,并且我绑定到一个实体列表。我拥有的实体有一个
系统.Drawing.Image
,我想显示它,但到目前为止,我还无法确定如何将其绑定到

我在互联网上找到的每一个示例和文档都与可通过
uri访问的图像有关,即硬盘或网站上的文件

    <DataTemplate x:Key="LogoPreviewItem">
        <Border BorderBrush="Black" BorderThickness="1">
            <DockPanel Width="150" Height="100">
                <Image>
                    <Image.Source>
                        <!--
                            {Binding PreviewImage} is where the System.Drawing.Image
                            is in this context
                        -->
                    </Image.Source>
                </Image>
                <Label DockPanel.Dock="Bottom" Content="{Binding CustomerName}" />
            </DockPanel>
        </Border>
    </DataTemplate>

System.Drawing.Image是一个WinForms/GDI+对象,在WPF世界中确实不合适。纯WPF程序通常不使用System.Drawing.Image,而是使用BitmapSource。然而,有时我们会被旧东西束缚一段时间

您可以将图像从旧技术转换为新技术,如下所示:

var oldImage = ...;  // System.Drawing.Image

var oldBitmap =
  oldImage as System.Drawing.Bitmap ??
  new System.Drawing.Bitmap(oldImage);

var bitmapSource =
   System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
     oldBitmap.GetHbitmap(System.Drawing.Color.Transparent),
     IntPtr.Zero,
     new Int32Rect(0, 0, oldBitmap.Width, oldBitmap.Height),
     null);
现在您可以设置:

myImage.Source = bitmapSource;

这比其他地方描述的MemoryStream方法快得多,因为它从不将位图数据序列化为流。

System.Drawing.Image是WinForms/GDI+对象,在WPF世界中确实不合适。纯WPF程序通常不使用System.Drawing.Image,而是使用BitmapSource。然而,有时我们会被旧东西束缚一段时间

您可以将图像从旧技术转换为新技术,如下所示:

var oldImage = ...;  // System.Drawing.Image

var oldBitmap =
  oldImage as System.Drawing.Bitmap ??
  new System.Drawing.Bitmap(oldImage);

var bitmapSource =
   System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
     oldBitmap.GetHbitmap(System.Drawing.Color.Transparent),
     IntPtr.Zero,
     new Int32Rect(0, 0, oldBitmap.Width, oldBitmap.Height),
     null);
现在您可以设置:

myImage.Source = bitmapSource;

这比其他地方描述的MemoryStream方法快得多,因为它从不将位图数据序列化为流。

Ray Burns的答案导致内存泄漏,因为

oldBitmap.GetHbitmap(System.Drawing.Color.Transparent)
分配从未释放的内存

GetHbitmap
()文档中的“备注”所述:

您负责调用GDI DeleteObject方法来释放GDI位图对象使用的内存

在文档之后,通过导入并使用
DeleteObject()
,释放内存:

因此,Ray Burns的答案应修改为:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

...

var oldImage = ...;  // System.Drawing.Image

var oldBitmap =
  oldImage as System.Drawing.Bitmap ??
  new System.Drawing.Bitmap(oldImage);

var hOldBitmap = oldBitmap.GetHbitmap(System.Drawing.Color.Transparent);
var bitmapSource =
   System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
     hOldBitmap,
     IntPtr.Zero,
     new Int32Rect(0, 0, oldBitmap.Width, oldBitmap.Height),
     null);
DeleteObject(hOldBitmap);

Ray Burns的答案导致内存泄漏,因为

oldBitmap.GetHbitmap(System.Drawing.Color.Transparent)
分配从未释放的内存

GetHbitmap
()文档中的“备注”所述:

您负责调用GDI DeleteObject方法来释放GDI位图对象使用的内存

在文档之后,通过导入并使用
DeleteObject()
,释放内存:

因此,Ray Burns的答案应修改为:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

...

var oldImage = ...;  // System.Drawing.Image

var oldBitmap =
  oldImage as System.Drawing.Bitmap ??
  new System.Drawing.Bitmap(oldImage);

var hOldBitmap = oldBitmap.GetHbitmap(System.Drawing.Color.Transparent);
var bitmapSource =
   System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
     hOldBitmap,
     IntPtr.Zero,
     new Int32Rect(0, 0, oldBitmap.Width, oldBitmap.Height),
     null);
DeleteObject(hOldBitmap);
看一看,看一看