从storageFile中裁剪的图像在发布模式下变为空,但在调试模式下有效

时间:2018-09-04 20:56:54

标签: vb.net uwp windows-10

我在从 StorageFile 提取裁剪的图像并将其保存到另一个文件的功能时遇到问题。 我正在为uwp应用使用Visual Studio 2017,目标版本 10.0.16299

  

在调试模式下,它可以工作。

在释放模式下,可变像素变为空(请参见代码!) 为什么?

    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 :(得分:1)

如果您在代码中创建encodingOptions对象时指定了BitmapEncoder(代码中的propertySet)之一,而与编码器相关联的图像不支持,则会出现错误

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

您指定的propertySet可能不受支持。请参阅主题Decode and encode image metadata

  

•有关哪种图像文件类型支持哪些属性的详细信息,请参见Windows PropertiesPhoto Metadata PoliciesWIC image format native metadata queries

     

•如果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 代码中看到错误消息。