Xamarin Forms压缩旋转后图片无法在ListView中显示问题
解决Xamarin Forms中图片压缩旋转后无法在ListView显示的问题
结合你给出的Skia日志(SkAndroidCodec::NewFromStream returned null),这个报错说明图片流要么没有有效数据,要么读取位置不对,咱们来一步步修复代码里的问题:
核心问题分析
- MemoryStream读取位置错误:当你把旋转压缩后的图片写入
outputStream后,流的读写指针停留在末尾,ListView读取这个流时会从空的末尾开始,自然读不到图片数据。 - 原输入流被提前消耗:
BitmapFactory.DecodeStream会把传入的imageStream的Position移动到流的末尾,如果旋转角度为0直接返回原流,这个流已经没有可读取的内容了。 - 未回收原Bitmap:虽然这不是显示问题的直接原因,但会造成不必要的内存占用,最好补上回收逻辑。
修改后的完整代码
public static Stream RotateAndCompress(Stream imageStream, int rotationAngle) { // 先重置原流位置,确保DecodeStream能从头读取 imageStream.Position = 0; Bitmap bp = BitmapFactory.DecodeStream(imageStream); try { if (rotationAngle != 0) { var matrix = new Matrix(); matrix.PostRotate(rotationAngle); using (var rotatedImage = Bitmap.CreateBitmap(bp, 0, 0, bp.Width, bp.Height, matrix, true)) { MemoryStream outputStream = new MemoryStream(); rotatedImage.Compress(Bitmap.CompressFormat.Png, 80, outputStream); // 重置输出流位置到开头,让图片加载器能读取到数据 outputStream.Position = 0; return outputStream; } } else { // 旋转角度为0时,重置原流位置后再返回 imageStream.Position = 0; return imageStream; } } finally { // 回收原Bitmap,释放内存 bp?.Recycle(); } }
关键修改点说明
- 强制重置流的Position:
- 调用
BitmapFactory.DecodeStream前重置原流位置,确保解码能读取到完整的图片数据。 - 压缩完成后重置输出流位置,让ListView的图片加载器可以从流的开头读取有效内容。
- 调用
- 添加原Bitmap的回收:在
finally块中回收原bp对象,避免内存泄漏问题。 - 优化分支逻辑:对旋转角度为0的情况也做了流位置重置,确保原流能被正确复用。
这样调整后,处理后的图片流就能被ListView正常加载显示了。
内容的提问来源于stack exchange,提问作者Wael
相关产品推荐
相关产品推荐

