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

.NET MAUI中如何在相机视图绘制矩形并裁剪身份证区域?

实现相机视图居中矩形框选并裁剪身份证的方案

跨平台可行方案(基于.NET MAUI)

因为Xamarin Forms已被.NET MAUI替代,推荐使用官方支持的组件组合实现:

  • MediaElement:用于相机预览显示
  • SkiaSharp:用于在预览上层绘制居中矩形,同时处理图像裁剪

步骤与代码示例

  1. 安装依赖包:Microsoft.Maui.Controls.MediaElement 和 SkiaSharp.Views.Maui
  2. XAML布局(叠加相机预览与绘图画布):
<Grid>
    <MediaElement x:Name="CameraPreview" Source="Camera" IsPlaying="True" />
    <skia:SKCanvasView x:Name="OverlayCanvas" PaintSurface="OverlayCanvas_PaintSurface" />
    <Button Text="拍照裁剪" Clicked="CaptureAndCrop_Clicked" 
            HorizontalOptions="Center" VerticalOptions="End" Margin="0,0,0,20" />
</Grid>
  1. C#逻辑处理:
// 绘制居中身份证框
private void OverlayCanvas_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e)
{
    var canvas = e.Surface.Canvas;
    canvas.Clear();

    var previewWidth = CameraPreview.Width;
    var previewHeight = CameraPreview.Height;
    if (previewWidth == 0 || previewHeight == 0) return;

    // 身份证标准比例 85.6mm/54mm ≈1.585
    const double idCardRatio = 85.6 / 54;
    float rectWidth, rectHeight;

    // 根据预览尺寸适配矩形大小,保持居中
    if (previewWidth / previewHeight > idCardRatio)
    {
        rectHeight = (float)previewHeight * 0.8f;
        rectWidth = (float)(rectHeight * idCardRatio);
    }
    else
    {
        rectWidth = (float)previewWidth * 0.8f;
        rectHeight = (float)(rectWidth / idCardRatio);
    }

    float x = (float)(previewWidth - rectWidth) / 2;
    float y = (float)(previewHeight - rectHeight) / 2;

    // 绘制红色边框
    using var paint = new SkiaSharp.SKPaint
    {
        Color = SkiaSharp.SKColors.Red,
        Style = SkiaSharp.SKPaintStyle.Stroke,
        StrokeWidth = 4,
        IsAntialias = true
    };
    canvas.DrawRect(x, y, rectWidth, rectHeight, paint);
}

// 拍照并裁剪图像
private async void CaptureAndCrop_Clicked(object sender, EventArgs e)
{
    var capturedImage = await CameraPreview.CapturePhotoAsync();
    if (capturedImage == null) return;

    // 解码捕获的图像
    using var bitmap = SkiaSharp.SKBitmap.Decode(capturedImage.FullPath);
    var imageWidth = bitmap.Width;
    var imageHeight = bitmap.Height;

    // 计算裁剪区域(与预览框比例一致)
    const double idCardRatio = 85.6 / 54;
    int cropWidth, cropHeight;
    if (imageWidth / imageHeight > idCardRatio)
    {
        cropHeight = (int)(imageHeight * 0.8f);
        cropWidth = (int)(cropHeight * idCardRatio);
    }
    else
    {
        cropWidth = (int)(imageWidth * 0.8f);
        cropHeight = (int)(cropWidth / idCardRatio);
    }

    int x = (imageWidth - cropWidth) / 2;
    int y = (imageHeight - cropHeight) / 2;

    // 执行裁剪
    using var croppedBitmap = bitmap.Subset(new SkiaSharp.SKRectI(x, y, x + cropWidth, y + cropHeight));
    // 输出裁剪后的图像(示例:转成流存储或显示)
    using var imageStream = new MemoryStream();
    croppedBitmap.Encode(SkiaSharp.SKEncodedImageFormat.Jpeg, 90).SaveTo(imageStream);
    imageStream.Position = 0;
    // 后续处理逻辑...
}

平台原生替代方案

如果需要更精细的控制,可使用平台原生API:

  • Android:采用CameraX实现预览,自定义SurfaceView叠加绘制矩形,通过ImageCapture获取图像后裁剪
  • iOS:基于AVFoundation创建预览层,添加CAShapeLayer绘制矩形,捕获图像后用CoreGraphics裁剪

注意事项

  • 需在项目中配置相机、存储权限(AndroidManifest.xml/Info.plist)
  • 可调整代码中0.8f的缩放系数,让矩形更贴合实际身份证大小
  • 若相机预览与捕获图像比例不一致,需额外做坐标映射(上述示例已按比例适配,可满足大部分场景)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:30:42