如何使用值转换器将字节数组绑定到WPF中的图像?

时间:2009-03-26 16:17:14

标签: .net wpf data-binding xaml image

我正在尝试将字节数组从我的数据库绑定到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()函数的i mage.EndInit()行抛出此 NotSupportedException

  

“没有适合的成像组件   完成此操作被发现。“

     

InnerException:“来自的异常   HRESULT:0x88982F50“

我不明白我做错了什么。我怎样才能使这个工作?


更新

似乎问题是来自数据库的字节。我把它们放进去的方式肯定存在问题。

请参阅下面的工作代码。

5 个答案:

答案 0 :(得分:20)

可以将byte []绑定到Image。

这是一个示例:

的Xaml:

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

代码:

private byte[] userImage;

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

答案 1 :(得分:11)

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

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

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

这是我的值转换器,用于将Byte数组绑定到Image ...

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}}" />

答案 2 :(得分:2)

尝试使用此

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

答案 3 :(得分:1)

我认为这实际上是一个安全权限问题。尝试使用管理员权限运行,看看是否有效,然后从那里开始。

编辑:我不赞成downvote和评论。看看这个链接:

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

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

答案 4 :(得分:1)

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

字节数组应该采用什么格式?你可以将它保存到磁盘,并尝试用另一个成像程序打开它吗?