Преобразование образа SQL в WPF ImageBrush [дубликат]

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

Краткая сводка

  1. Есть две проблемы с float сравнивает: у вас ограниченная точность и значение «приблизительно нуля» зависит от контекста (см. следующую точку).
  2. Является ли 1E-8 примерно таким же, как 1E-16? Если вы смотрите на шумные данные датчиков, то, вероятно, да, но если вы делаете молекулярное моделирование, то может и не быть! Итог: вам всегда нужно думать о значении tolerance в контексте конкретного вызова функции, а не просто делать его общей жестко запрограммированной константой приложения.
  3. Для общих функций библиотеки, по-прежнему приятно иметь параметр с допустимым значением по умолчанию . Типичным выбором является numeric_limits::epsilon(), который аналогичен FLT_EPSILON в float.h. Это, однако, проблематично, потому что epsilon для сравнения значений типа 1.0, если не такой же, как epsilon, для значений, подобных 1E9. FLT_EPSILON определен для 1.0.
  4. Очевидная реализация для проверки того, находится ли число в пределах допуска fabs(a-b) <= epsilon, однако это не работает, потому что по умолчанию epsilon определен для 1.0. Нам нужно масштабировать epsilon вверх или вниз в терминах a и b.
  5. Существует два решения этой проблемы: либо вы устанавливаете epsilon пропорционально max(a,b), либо можете получить следующие отображаемые числа вокруг a, а затем см., если b попадает в этот диапазон. Первый метод называется «относительным», а позже называется методом ULP.
  6. Оба метода на самом деле терпят неудачу в любом случае при сравнении с 0. В этом случае приложение должно предоставлять правильный допуск.

Реализация служебных функций (C ++ 11)

//implements relative method - do not use for comparing with zero
//use this most of the time, tolerance needs to be meaningful in your context
template<typename TReal>
static bool isApproximatelyEqual(TReal a, TReal b, TReal tolerance = std::numeric_limits<TReal>::epsilon())
{
    TReal diff = std::fabs(a - b);
    if (diff <= tolerance)
        return true;

    if (diff < std::fmax(std::fabs(a), std::fabs(b)) * tolerance)
        return true;

    return false;
}

//supply tolerance that is meaningful in your context
//for example, default tolerance may not work if you are comparing double with float
template<typename TReal>
static bool isApproximatelyZero(TReal a, TReal tolerance = std::numeric_limits<TReal>::epsilon())
{
    if (std::fabs(a) <= tolerance)
        return true;
    return false;
}


//use this when you want to be on safe side
//for example, don't start rover unless signal is above 1
template<typename TReal>
static bool isDefinitelyLessThan(TReal a, TReal b, TReal tolerance = std::numeric_limits<TReal>::epsilon())
{
    TReal diff = a - b;
    if (diff < tolerance)
        return true;

    if (diff < std::fmax(std::fabs(a), std::fabs(b)) * tolerance)
        return true;

    return false;
}
template<typename TReal>
static bool isDefinitelyGreaterThan(TReal a, TReal b, TReal tolerance = std::numeric_limits<TReal>::epsilon())
{
    TReal diff = a - b;
    if (diff > tolerance)
        return true;

    if (diff > std::fmax(std::fabs(a), std::fabs(b)) * tolerance)
        return true;

    return false;
}

//implements ULP method
//use this when you are only concerned about floating point precision issue
//for example, if you want to see if a is 1.0 by checking if its within
//10 closest representable floating point numbers around 1.0.
template<typename TReal>
static bool isWithinPrecisionInterval(TReal a, TReal b, unsigned int interval_size = 1)
{
    TReal min_a = a - (a - std::nextafter(a, std::numeric_limits<TReal>::lowest())) * interval_size;
    TReal max_a = a + (std::nextafter(a, std::numeric_limits<TReal>::max()) - a) * interval_size;

    return min_a <= b && max_a >= b;
}
12
задан Zack Peterson 26 March 2009 в 20:17
поделиться

5 ответов

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

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

Это мой преобразователь значений, используемый для привязки байтового массива к изображению & 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}}" />
11
ответ дан Zack Peterson 20 August 2018 в 20:39
поделиться

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

Dim imageSource as ImageSource
Dim bitmapDecoder = new PngBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
imageSource = bitmapDecoder.Frames[0];
imageSource.Freeze();
Return imageSource
2
ответ дан bendewey 20 August 2018 в 20:39
поделиться
  • 1
    Это вызывает одно и то же исключение в «bitmapDecoder = Dim» = линия. – Zack Peterson 26 March 2009 в 17:57
  • 2
    Ваше изображение в формате PNG? – bendewey 26 March 2009 в 18:01
  • 3
    Нет. Это JPEG. Но JpegBitmapDecoder также терпит неудачу. – Zack Peterson 26 March 2009 в 18:07
  • 4
    Если вы сохраняете изображение непосредственно в FileStream, оно успешно открывается? – bendewey 26 March 2009 в 18:16
  • 5
    Кроме того, в вашем обновлении вы читаете изображение из потока и затем помещаете данные этого объекта изображения в базу данных. почему бы просто не загрузить FileOpenStream напрямую в базу данных? – bendewey 26 March 2009 в 18:19

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

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

1
ответ дан casperOne 20 August 2018 в 20:39
поделиться
  • 1
    Это создает файл 24245 байт, который не может быть прочитан Windows Picture и Fax Viewer. – Zack Peterson 26 March 2009 в 19:29
  • 2
    @Zack: Тогда это означает, что мой ответ был верным, у вас неверный формат для файла изображения (либо это, либо способ, которым вы получаете / обрабатываете байты, является неправильным и развращает его). – casperOne 26 March 2009 в 19:52
18
ответ дан Charlie 20 August 2018 в 20:39
поделиться

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

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

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

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

1
ответ дан Razzie 20 August 2018 в 20:39
поделиться
  • 1
    @Razzie: Скорее всего, нет, учитывая код ошибки. – casperOne 26 March 2009 в 17:26
Другие вопросы по тегам:

Похожие вопросы: