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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/686461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:24:20  来源:igfitidea点击:

How do I bind a Byte array to an Image in WPF with a value converter?

.netwpfdata-bindingxamlimage

提问by Zack Peterson

I'm trying to bind a Byte array from my databse to a WPF Image.

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

My XAML:

我的 XAML:

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

I've modified code published by Ryan Cromwellfor a value converter:

我已经修改了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

The image.EndInit()line of the BinaryImageConverter's Convert() function throws this NotSupportedException:

mage.EndInit()BinaryImageConverter 的 Convert() 函数的 i行抛出这个NotSupportedException

"No imaging component suitable to complete this operation was found."

InnerException: "Exception from HRESULT: 0x88982F50"

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

内部异常:“来自 HRESULT 的异常:0x88982F50”

I don't understand what I'm doing wrong. How can I get this working?

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



Update

更新

It seems the problem was the bytes coming out of the database. There must have been a problem with the way I was putting them in.

问题似乎是从数据库中出来的字节。我把它们放进去的方式一定有问题。

See my working code below.

请参阅下面的我的工作代码。

采纳答案by Zack Peterson

Thanks for all your help. I've now got it working. I'm still not sure exactly what the problem was.

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

This is how I put images into my database…

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

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

This is my value converter used to bind a Byte array to an 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

This is my XAML that uses the converter display the image…

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

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

回答by sebastianb

You canbind a byte[] to an Image.

可以将 byte[] 绑定到 Image。

Here a Sample:

这是一个示例:

Xaml:

Xml:

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

Code:

代码:

private byte[] userImage;

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

回答by bendewey

Try using this

尝试使用这个

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

回答by Razzie

I believe this is actually a security permission issue. Try running with administrator privileges, and see if that works, and go from there.

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

EDIT: I disagree with the downvote and comment. Take a look at this link:

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

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

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

This user had the exact same error, and it was caused by security settings. Therefore, I stand by my answer (which may not be the cause, but it is certainly worth a try)

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

回答by casperOne

My guess would be that the bytes are not a legitimate image format. I believe that error code corresponds to WINCODEC_ERR_COMPONENTNOTFOUND, which would be consistent with invalid bytes.

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

What format is the byte array supposed to be in? Can you save it to disk, and try to open it with another imaging program?

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