Обрезанное изображение из storageFile становится нулевым в режиме выпуска, но работает в режиме отладки - PullRequest
0 голосов
/ 04 сентября 2018

У меня проблема с функцией, которая извлекает обрезанное изображение из StorageFile и сохраняет его в другом файле. Я использую visual studio 2017, целевая версия 10.0.16299 для приложения uwp.

В режиме отладки работает.

В режиме выпуска переменные пиксели становятся нулевыми (пожалуйста, смотрите код !!) почему ??

    Private Shared Async Function GetPixelData(decoder As BitmapDecoder, startPointX As UInteger, startPointY As UInteger, width As UInteger, height As UInteger, scaledWidth As UInteger,
        scaledHeight As UInteger) As Task(Of Byte())
        Dim transform As New BitmapTransform()
        Dim bounds As New BitmapBounds()
        bounds.X = startPointX
        bounds.Y = startPointY
        bounds.Height = height
        bounds.Width = width
        transform.Bounds = bounds
        transform.ScaledWidth = scaledWidth
        transform.ScaledHeight = scaledHeight
        Dim pix As PixelDataProvider = Await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.ColorManageToSRgb)
        Dim pixels As Byte() = pix.DetachPixelData()
        Return pixels
    End Function

'Получить обрезанное изображение из файла хранилища и сохранить на новый файл хранилища

Public Shared Async Function SaveCroppedBitmapAsync(originalImageFile As StorageFile, newImageFile As StorageFile, startPoint As Point, cropSize As Size) As Task
        Dim startPointX As UInteger = CUInt(Math.Floor(startPoint.X))
        Dim startPointY As UInteger = CUInt(Math.Floor(startPoint.Y))
        Dim height As UInteger = CUInt(Math.Floor(cropSize.Height))
        Dim width As UInteger = CUInt(Math.Floor(cropSize.Width))
        Using originalImgFileStream As IRandomAccessStream = Await originalImageFile.OpenReadAsync()

                Dim decoder As BitmapDecoder = Await BitmapDecoder.CreateAsync(originalImgFileStream)

                 If startPointX + width > decoder.PixelWidth Then
                startPointX = decoder.PixelWidth - width
            End If

            If startPointY + height > decoder.PixelHeight Then
                startPointY = decoder.PixelHeight - height
            End If

                       Using newImgFileStream As IRandomAccessStream = Await newImageFile.OpenAsync(FileAccessMode.ReadWrite)
                Dim pixels As Byte() = Await GetPixelData(decoder, startPointX, startPointY, width, height, decoder.PixelWidth,
                    decoder.PixelHeight)

                Dim encoderID As New Guid
                encoderID = Guid.Empty

                Select Case newImageFile.FileType.ToLower()
                    Case ".png"
                        encoderID = BitmapEncoder.PngEncoderId
                        Exit Select
                    Case ".bmp"
                        encoderID = BitmapEncoder.BmpEncoderId
                        Exit Select
                    Case Else
                        encoderID = BitmapEncoder.JpegEncoderId
                        Exit Select
                End Select

                Dim propertySet As New BitmapPropertySet()

                              If decoder.PixelWidth > 3000 Or decoder.PixelHeight > 3000 Then
                    Dim qualityValue As New BitmapTypedValue(0.4, PropertyType.Single)
                    propertySet.Add("ImageQuality", qualityValue)
                Else
                    Dim qualityValue As New BitmapTypedValue(0.7, PropertyType.Single)
                    propertySet.Add("ImageQuality", qualityValue)
                End If

                            Dim bmpEncoder As BitmapEncoder = Await BitmapEncoder.CreateAsync(encoderID, newImgFileStream, propertySet)

''''''''' Exception in this point,  pixel becomes null!!!! why????

                bmpEncoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, width, height, decoder.DpiX, decoder.DpiY,
                        pixels)

                Await bmpEncoder.FlushAsync()

            End Using
        End Using
    End Function

Спасибо!

1 Ответ

0 голосов
/ 05 сентября 2018

Вы получите ошибку, если вы указали одну из encodingOptions (propertySet в вашем коде), которая не поддерживается изображением, связанным с кодировщиком, когда вы создаете объект BitmapEncoder в код

Dim bmpEncoder As BitmapEncoder = Await BitmapEncoder.CreateAsync(encoderID, newImgFileStream, propertySet)

Указанное вами propertySet может не поддерживаться. Смотрите тему Декодируйте и кодируйте метаданные изображения ,

• Подробнее о том, какие свойства поддерживаются для каких типов файлов изображений, см. Свойства Windows , Политики метаданных фото и Запросы собственных метаданных формата изображения WIC .

SetPropertiesAsync завершится ошибкой с кодом ошибки 0x88982F41, если одно из запрошенных свойств не поддерживается изображением, связанным с кодировщиком.

Вы можете изменить свой код без установки свойства, чтобы он работал:

...

Dim bmpEncoder As BitmapEncoder = Await BitmapEncoder.CreateAsync(encoderID, newImgFileStream)

Try
    Await bmpEncoder.BitmapProperties.SetPropertiesAsync(propertySet)
Catch ex As Exception
    Debug.WriteLine(ex.Message)
End Try

...

В части Try Catch вы можете увидеть сообщение об ошибке в коде Debug , если запрошенное свойство не поддерживается.

...