Как связать массив байтов с изображением в WPF с помощью преобразователя значений? - PullRequest
12 голосов
/ 26 марта 2009

Я пытаюсь связать массив байтов из моей базы данных с образом 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

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

"Нет компонента, подходящего для выполнить эту операцию было найдено. "

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

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


Обновление

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

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

Ответы [ 5 ]

21 голосов
/ 08 декабря 2011

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

Вот образец:

Xaml:

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

Код:

private byte[] userImage;

public byte[] UserImage
   {
       get { return userImage; }
       set
       {
           if (value != userImage)
           {
               userImage = value;
               OnPropertyChanged("UserImage");
           }
       }
   }
11 голосов
/ 26 марта 2009

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

Вот как я помещаю изображения в свою базу данных & 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 голосов
/ 26 марта 2009

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

Dim imageSource as ImageSource
Dim bitmapDecoder = new PngBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
imageSource = bitmapDecoder.Frames[0];
imageSource.Freeze();
Return imageSource
1 голос
/ 26 марта 2009

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

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

1 голос
/ 26 марта 2009

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

РЕДАКТИРОВАТЬ: я не согласен с downvote и комментарием. Взгляните на эту ссылку:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...