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

MAUI Android中如何获取SKCanvasView的完整尺寸以全屏绘制SKImage

MAUI Android中如何获取SKCanvasView的完整尺寸以全屏绘制SKImage

嗨,我来帮你解决这个问题!你遇到的核心问题是混淆了MAUI的逻辑尺寸和SkiaSharp画布的物理像素尺寸,下面我一步步给你讲清楚怎么处理:

问题根源

在MAUI里,canvasView.Width和Height返回的是逻辑尺寸(单位是与设备无关的像素dp),而Android设备普遍存在像素密度缩放(比如常见的2x、3x屏幕),SkiaSharp的画布实际使用的是物理像素。直接用逻辑尺寸绘制的话,相当于把图像缩放到了1/密度比的大小,所以才会出现只显示一半的情况。

正确解决方案

在PaintSurface事件处理方法里,你应该从事件参数SKPaintSurfaceEventArgs的Info属性中获取画布的真实物理尺寸,这个值已经自动适配了设备的像素密度。

步骤1:确保SKCanvasView占满整个窗口

首先,你需要让SKCanvasView本身充满整个页面,在代码创建它的时候加上布局选项:

public MainPage()
{
    InitializeComponent();
    // ... 其他初始化代码
    canvasView = new SKCanvasView();
    // 设置布局选项,让View占满可用空间
    canvasView.HorizontalOptions = LayoutOptions.FillAndExpand;
    canvasView.VerticalOptions = LayoutOptions.FillAndExpand;
    canvasView.PaintSurface += CanvasView_PaintSurface;
    Content = canvasView;
}

步骤2:使用画布的真实尺寸绘制图像

修改PaintSurface方法,改用e.Info.Size来获取画布的宽高:

private void CanvasView_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e)
{
    var cv = e.Surface.Canvas;          
    cv.Clear(new SKColor(0, 0, 255));   

    // 获取画布的实际物理像素尺寸
    var canvasSize = e.Info.Size;
    // 用这个尺寸绘制图像,就能铺满整个画布了
    cv.DrawImage(image, new SKRect(0.0f, 0.0f, canvasSize.Width, canvasSize.Height));
}

额外提示:保持图像比例(可选)

如果你的图像比例和画布比例不一致,直接拉伸可能会变形。如果需要保持图像比例并居中显示,可以这样计算:

private void CanvasView_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e)
{
    var cv = e.Surface.Canvas;          
    cv.Clear(new SKColor(0, 0, 255));   

    var canvasSize = e.Info.Size;
    if (image == null) return;

    // 计算缩放比例,保持图像比例
    float scaleX = canvasSize.Width / image.Width;
    float scaleY = canvasSize.Height / image.Height;
    // 选择最小的缩放比例,保证图像完全显示;如果要铺满用Math.Max
    float scale = Math.Min(scaleX, scaleY);

    // 计算缩放后的图像尺寸
    float scaledWidth = image.Width * scale;
    float scaledHeight = image.Height * scale;

    // 计算居中位置
    float posX = (canvasSize.Width - scaledWidth) / 2;
    float posY = (canvasSize.Height - scaledHeight) / 2;

    // 绘制居中且保持比例的图像
    cv.DrawImage(image, new SKRect(posX, posY, posX + scaledWidth, posY + scaledHeight));
}

这样修改后,你的SKImage就能正确铺满整个SKCanvasView了!

备注:内容来源于stack exchange,提问作者Alex F

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 09:44:37