BitmapEncoder.FlushAsync失效,求将SoftwareBitmap写入流的高效替代方案
替代BitmapEncoder.FlushAsync()保存SoftwareBitmap到流的方法
我碰到过类似的问题,给你几个可行的解决方案,按实用性排序:
1. 使用TryCommitAsync()替代FlushAsync()
这是最直接的替代方案,TryCommitAsync()在很多FlushAsync()失效的场景下都能正常工作,而且它不会抛出异常,而是返回布尔值表示操作是否成功,调试和错误处理更灵活。
同时要注意:确保SoftwareBitmap的像素格式与编码器兼容,很多时候FlushAsync()失败都是因为格式不匹配(比如JPG编码器不支持BGRA8格式),所以先做格式检查和转换很重要。
修改后的代码示例:
using (InMemoryRandomAccessStream accessStream = new InMemoryRandomAccessStream()) { BitmapEncoder encoder = await BitmapEncoder.CreateAsync(_inputFormat, accessStream); // 检查并转换为编码器支持的像素格式 if (!encoder.IsPixelFormatSupported(input.BitmapPixelFormat)) { // 这里以BGRA8为例,你可以根据编码器类型选择合适的格式 input = SoftwareBitmap.Convert(input, BitmapPixelFormat.Bgra8); } encoder.SetSoftwareBitmap(input); encoder.IsThumbnailGenerated = true; // 用TryCommitAsync替代FlushAsync bool isCommitted = await encoder.TryCommitAsync(); if (isCommitted) { // 操作成功,重置流指针到开头以便后续读取 accessStream.Seek(0); // 这里添加你的后续逻辑,比如保存到文件或传输数据 } else { // 处理提交失败的情况 Debug.WriteLine("Bitmap encoder commit failed"); } }
2. 直接写入原始像素数据到流
如果你不需要编码成特定的图片格式(比如PNG/JPG),只是想保存SoftwareBitmap的原始像素数据,可以绕开BitmapEncoder,直接操作像素缓冲区:
using (InMemoryRandomAccessStream accessStream = new InMemoryRandomAccessStream()) { // 锁定SoftwareBitmap的像素缓冲区 using (BitmapBuffer buffer = input.LockBuffer(BitmapBufferAccessMode.Read)) { byte[] pixelData = new byte[buffer.Length]; // 将缓冲区数据复制到字节数组 await buffer.CopyToAsync(pixelData.AsBuffer()); // 写入到流中 await accessStream.WriteAsync(pixelData.AsBuffer()); } // 重置流指针到开头 accessStream.Seek(0); // 后续操作... }
3. 检查编码器配置细节
如果上面的方法都不行,你可以尝试关闭缩略图生成(把encoder.IsThumbnailGenerated = true改成false),有时候缩略图生成的异常会导致FlushAsync()失败,但不会明确抛出错误。另外,也可以尝试指定编码器的其他参数(比如JPG的质量),排除参数配置问题。
内容的提问来源于stack exchange,提问作者Sarnapa
相关产品推荐
相关产品推荐

