Как связать массив байтов с изображением в WPF с преобразователем значений?

Я пытаюсь связать массив байтов от моей базы данных к изображению WPF.

Мой XAML:

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

Я изменил код, опубликованный Райан Кромвелл для конвертера значений:

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

Линия я mage.EndInit() функции BinaryImageConverter Convert() выдает это NotSupportedException:

"Никакой компонент изображения, подходящий для завершена эта операция."

InnerException: "Исключение из HRESULT: 0x88982F50"

Я не понимаю, что я делаю неправильно. Как я могу заставить это работать?


Update

Кажется, проблема заключалась в том, что байты выходят из базы данных. Должна была быть проблема с тем, как я их вставлял.

См. мой рабочий код ниже.

Ответ 1

Спасибо за вашу помощь. Теперь у меня это работает. Я все еще не уверен, в чем проблема.

Вот как я помещал изображения в мою базу данных & hellip;

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

Это мой преобразователь значений, используемый для привязки байтового массива к Image & hellip;

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, который использует конвертер, отображающий изображение & hellip;

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

Ответ 2

Вы можете привязать байт [] к изображению.

Здесь пример:

Xaml:

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

код:

private byte[] userImage;

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

Ответ 3

Попробуйте использовать

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

Ответ 4

Я считаю, что на самом деле это проблема с безопасностью. Попробуйте запустить с правами администратора и посмотрите, работает ли это, и оттуда.

EDIT: Я не согласен с нижним рейтингом и комментариями. Взгляните на эту ссылку:

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

У этого пользователя была такая же ошибка, и это было вызвано параметрами безопасности. Поэтому я поддерживаю свой ответ (что может и не быть причиной, но, безусловно, стоит попробовать)

Ответ 5

Я предполагаю, что байты не являются законным форматом изображения. Я считаю, что код ошибки соответствует WINCODEC_ERR_COMPONENTNOTFOUND, что согласуется с недопустимыми байтами.

В каком формате должен использоваться массив байтов? Можете ли вы сохранить его на диск и попытаться открыть его с помощью другой программы обработки изображений?