You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
    }
}

关键修改点说明

  1. 强制重置流的Position:
    • 调用BitmapFactory.DecodeStream前重置原流位置,确保解码能读取到完整的图片数据。
    • 压缩完成后重置输出流位置,让ListView的图片加载器可以从流的开头读取有效内容。
  2. 添加原Bitmap的回收:在finally块中回收原bp对象,避免内存泄漏问题。
  3. 优化分支逻辑:对旋转角度为0的情况也做了流位置重置,确保原流能被正确复用。

这样调整后,处理后的图片流就能被ListView正常加载显示了。

内容的提问来源于stack exchange,提问作者Wael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:34:33