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

Xamarin.Forms加载SMB大图片遇Drawing too large bitmap错误求解决方案

解决Xamarin.Forms加载SMB大图片时的"Drawing too large bitmap"错误

你的问题根源在于图片的像素尺寸超过了Android系统允许的最大位图大小,而不是文件体积——你之前判断stream1.Length的方式只限制了文件大小,对像素尺寸无效。要解决这个问题,需要在将图片流转为ImageSource之前,先压缩图片的分辨率。

推荐使用跨平台图形库SkiaSharp来处理图片压缩,无需编写平台特定代码,步骤如下:

1. 添加SkiaSharp依赖

在你的Xamarin.Forms项目中安装NuGet包:SkiaSharp.Views.Forms

2. 编写图片压缩方法

添加一个用于调整图片流分辨率的工具方法:

private Stream ResizeImageStream(Stream inputStream, int maxWidth, int maxHeight)
{
    using var originalBitmap = SKBitmap.Decode(inputStream);
    int originalWidth = originalBitmap.Width;
    int originalHeight = originalBitmap.Height;

    // 计算缩放比例,保持图片宽高比
    float scaleFactor = Math.Min((float)maxWidth / originalWidth, (float)maxHeight / originalHeight);

    // 如果原图尺寸小于等于目标尺寸,直接返回原流
    if (scaleFactor >= 1)
    {
        inputStream.Position = 0;
        return inputStream;
    }

    int newWidth = (int)(originalWidth * scaleFactor);
    int newHeight = (int)(originalHeight * scaleFactor);

    // 生成压缩后的位图
    using var resizedBitmap = originalBitmap.Resize(new SKImageInfo(newWidth, newHeight), SKFilterQuality.High);
    using var image = SKImage.FromBitmap(resizedBitmap);
    // 编码为JPEG,质量80(可根据需求调整,范围0-100)
    using var data = image.Encode(SKEncodedImageFormat.Jpeg, 80);

    var outputStream = new MemoryStream();
    data.SaveTo(outputStream);
    outputStream.Position = 0;
    return outputStream;
}

3. 修改原有加载图片的代码

替换你原有的图片加载逻辑,加入压缩处理:

if (!String.IsNullOrEmpty(CurrentProduct.Image))
{
    SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8080");
    var auth = new NtlmPasswordAuthentication("CLD", "login", "password");
    string path = $@"smb://file/products/{CurrentProduct.Image}".Replace("\\", "/");

    var file = new SmbFile(path, auth);
    try
    {
        if (file.Exists())
        {
            // 使用using自动释放流,避免内存泄漏
            using var readStream = file.GetInputStream();
            using var memStream = new MemoryStream();
            readStream.CopyTo(memStream);
            memStream.Position = 0;

            // 压缩图片到最大1080x1920(可根据你的UI需求调整尺寸)
            using var resizedStream = ResizeImageStream(memStream, 1080, 1920);

            // 生成ImageSource时,需要重新复制流(因为Stream只能读取一次)
            ProductImage = ImageSource.FromStream(() =>
            {
                var stream = new MemoryStream();
                resizedStream.Position = 0;
                resizedStream.CopyTo(stream);
                stream.Position = 0;
                return stream;
            });

            InfoColSpan = 1;
        }
    }
    catch (Exception ex)
    {
        Common.AlertError(ex, "Impossible de charger l'image");
    }
}

关键说明

  • 宽高比保持:压缩时通过计算最小缩放比例,确保图片不会被拉伸变形
  • 尺寸调整:你可以根据应用的UI显示需求,修改ResizeImageStream方法中的maxWidth和maxHeight参数(比如设置为设备屏幕的分辨率)
  • 内存优化:使用using语句自动释放流和位图资源,避免内存泄漏
  • 替代方案:如果不想使用SkiaSharp,也可以通过Xamarin.Forms的依赖服务调用平台原生API(比如Android的BitmapFactory.Options设置inSampleSize),但跨平台实现复杂度更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:45:56