vb.net - 来自 storageFile 的裁剪图像在发布模式下变为空,但在调试模式下有效
问题描述
我有一个从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
谢谢!
解决方案
如果您在代码中创建BitmapEncoder对象时指定了与编码器关联的图像不支持的encodingOptions之一(在您的代码中),您将收到错误propertySet
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代码中看到错误消息。
推荐阅读
- oop - Julia 中的享元/OOP 设计模式
- javascript - 事件触发函数的返回值
- android - 以 29(Q) 作为目标 API 的 28(P) 的 EditText 句柄颜色
- powershell - 变量内部的Powershell点源变量不扩展
- python - 将 Jaro-Winkler 距离应用于数据帧
- javascript - 如何使用旧的 JavaScript 从这个字符串(代表 URL)中删除这个 URL 部分?
- excel - 如何解决:比较两张纸并输出匹配代码?
- python - 如何将数据发送到事件中心并安排它每 10 秒运行一次?
- c++ - 无法调试可能的 Rcpp 内存泄漏
- azure - 开发多个 Azure DevOps 自定义任务时的正确文件结构