【问题标题】:How do I bind a Byte array to an Image in WPF with a value converter?如何使用值转换器将字节数组绑定到 WPF 中的图像?
【发布时间】:2010-10-15 17:55:59
【问题描述】:

我正在尝试将 Byte 数组从我的数据库绑定到 WPF 图像。

我的 XAML:

<Window.Resources>
    <local:BinaryImageConverter x:Key="imgConverter" />
</Window.Resources>
...
<Image Source="{Binding Path=ImageData, Converter={StaticResource imgConverter}}" />

我已经修改了Ryan Cromwell 发布的代码,用于值转换器:

Class BinaryImageConverter
    Implements IValueConverter
    Private Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
        If value IsNot Nothing AndAlso TypeOf value Is Byte() Then
            Dim bytes As Byte() = TryCast(value, Byte())
            Dim stream As New MemoryStream(bytes)
            Dim image As New BitmapImage()
            image.BeginInit()
            image.StreamSource = stream
            image.EndInit()
            Return image
        End If
        Return Nothing
    End Function
    Private Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New Exception("The method or operation is not implemented.")
    End Function
End Class

BinaryImageConverter 的 Convert() 函数的 image.EndInit() 行抛出此 NotSupportedException

"没有适合的成像组件 完成此操作已找到。”

InnerException: "异常来自 HRESULT: 0x88982F50"

我不明白我做错了什么。我怎样才能让它工作?


更新

问题似乎出在数据库中的字节数上。我放入它们的方式一定有问题。

在下面查看我的工作代码。

【问题讨论】:

    标签: .net wpf data-binding xaml image


    【解决方案1】:

    可以将 byte[] 绑定到 Image。

    这里是一个示例:

    Xaml:

    <Image Source="{Binding UserImage}"/>
    

    代码:

    private byte[] userImage;
    
    public byte[] UserImage
       {
           get { return userImage; }
           set
           {
               if (value != userImage)
               {
                   userImage = value;
                   OnPropertyChanged("UserImage");
               }
           }
       }
    

    【讨论】:

    • 我尝试了您的解决方案。但我收到类似Can't convert type System.Byte[] to type System.Windows.Media.ImageSource 的错误
    • 可能是因为我正在为 Windows phone 开发。
    • 不确定 2013 年,但在 .NET 4.5 上将 byte[] 直接绑定到 Image 工作正常
    【解决方案2】:

    感谢您的所有帮助。我现在已经开始工作了。我仍然不确定到底是什么问题。

    这就是我将图像放入数据库的方式……

    Private Sub ButtonUpload_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim FileOpenStream As Stream = Nothing
        Dim FileBox As New Microsoft.Win32.OpenFileDialog()
        FileBox.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
        FileBox.Filter = "Pictures (*.jpg;*.jpeg;*.gif;*.png)|*.jpg;*.jpeg;*.gif;*.png|" & _
                         "All Files (*.*)|*.*"
        FileBox.FilterIndex = 1
        FileBox.Multiselect = False
        Dim FileSelected As Nullable(Of Boolean) = FileBox.ShowDialog(Me)
        If FileSelected IsNot Nothing AndAlso FileSelected.Value = True Then
            Try
                FileOpenStream = FileBox.OpenFile()
                If (FileOpenStream IsNot Nothing) Then
    
                    Dim ByteArray As Byte()
                    Using br As New BinaryReader(FileOpenStream)
                        ByteArray = br.ReadBytes(FileOpenStream.Length)
                    End Using
    
                    Dim g As New ZackGraphic
                    g.Id = Guid.NewGuid
                    g.ImageData = ByteArray
                    g.FileSize = CInt(ByteArray.Length)
                    g.FileName = FileBox.FileName.Split("\").Last
                    g.FileExtension = "." + FileBox.FileName.Split(".").Last.ToLower
                    g.DateAdded = Now
    
                    Dim bmp As New BitmapImage
                    bmp.BeginInit()
                    bmp.StreamSource = New MemoryStream(ByteArray)
                    bmp.EndInit()
                    bmp.Freeze()
    
                    g.PixelWidth = bmp.PixelWidth
                    g.PixelHeight = bmp.PixelHeight
    
                    db.AddToZackGraphic(g)
                    db.SaveChanges()
    
                End If
            Catch Ex As Exception
                MessageBox.Show("Cannot read file from disk. " & Ex.Message, "Add a New Image", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK)
            Finally
                If (FileOpenStream IsNot Nothing) Then
                    FileOpenStream.Close()
                End If
            End Try
        End If
    End Sub
    

    这是我用来将字节数组绑定到图像的值转换器……

    Class BinaryImageConverter
        Implements IValueConverter
        Private Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
            If value IsNot Nothing AndAlso TypeOf value Is Byte() Then
                Dim ByteArray As Byte() = TryCast(value, Byte())
                Dim bmp As New BitmapImage()
                bmp.BeginInit()
                bmp.StreamSource = New MemoryStream(ByteArray)
                bmp.EndInit()
                Return bmp
            End If
            Return Nothing
        End Function
        Private Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
            Throw New Exception("The method or operation is not implemented.")
        End Function
    End Class
    

    这是我使用转换器显示图像的 XAML……

    <Window xmlns:local="clr-namespace:MyProjectName" ... >
        <Window.Resources>
            <local:BinaryImageConverter x:Key="imgConverter" />
        </Window.Resources>
    ...
    <Image Source="{Binding Path=ImageData, Converter={StaticResource imgConverter}}" />
    

    【讨论】:

      【解决方案3】:

      试试这个

      Dim imageSource as ImageSource
      Dim bitmapDecoder = new PngBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
      imageSource = bitmapDecoder.Frames[0];
      imageSource.Freeze();
      Return imageSource
      

      【讨论】:

      • 这会在“Dim bitmapDecoder =”行引发相同的异常。
      • 如果将图像直接保存到 FileStream 是否可以成功打开?
      • 此外,在您的更新中,您正在从流中读取图像,然后将该图像对象的数据放入数据库中。为什么不直接将 FileOpenStream 加载到数据库中?
      • bendewey,我将 ButtonUpload_Click() 方法更改为“使用 br 作为新的 BinaryReader(FileOpenStream)”,并使用该方法将图像重新添加到数据库中。我仍然遇到同样的异常。
      • 直接从数据库保存到磁盘怎么样?
      【解决方案4】:

      我的猜测是字节不是合法的图像格式。我认为错误码对应WINCODEC_ERR_COMPONENTNOTFOUND,这将与无效字节一致。

      字节数组应该采用什么格式?你能把它保存到磁盘上,然后尝试用另一个图像程序打开它吗?

      【讨论】:

      • 这会创建一个 24,425 字节的文件,Windows 图片和传真查看器无法读取该文件。
      • @Zack:那意味着我的回答是正确的,您的图像文件格式无效(或者您获取/处理字节的方式不正确并损坏了它)。
      【解决方案5】:

      我相信这实际上是一个安全权限问题。尝试以管理员权限运行,看看是否可行,然后从那里开始。

      编辑:我不同意反对票和评论。看看这个链接:

      http://social.expression.microsoft.com/Forums/en-US/wpf/thread/617f6711-0373-44cc-b72c-aeae20f0f7a8/

      这个用户有完全相同的错误,它是由安全设置引起的。因此,我坚持我的回答(这可能不是原因,但肯定值得一试)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-17
        • 2011-06-01
        • 2023-03-09
        相关资源
        最近更新 更多