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

如何在UWP中使用C#从照片中裁剪自定义形状?

UWP 自定义PNG模板形状裁剪实现

要实现基于PNG模板的自定义形状裁剪,你可以借助Win2D库(UWP下高效的图形处理工具),通过模板的Alpha通道作为遮罩,保留原图中对应模板白色形状的区域,其余部分设为透明。以下是完整实现方案:

前置准备

先通过NuGet安装Microsoft.Graphics.Win2D包,这是UWP处理复杂图形合成的必备依赖。

核心函数实现

using System;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Brushes;

public async Task CropImageByTemplateAsync(StorageFile sourceImageFile, StorageFile templateImageFile, StorageFile outputFile)
{
    // 加载原图与模板文件
    using (var sourceStream = await sourceImageFile.OpenAsync(FileAccessMode.Read))
    using (var templateStream = await templateImageFile.OpenAsync(FileAccessMode.Read))
    {
        CanvasBitmap sourceBitmap = await CanvasBitmap.LoadAsync(CanvasDevice.GetSharedDevice(), sourceStream);
        CanvasBitmap templateBitmap = await CanvasBitmap.LoadAsync(CanvasDevice.GetSharedDevice(), templateStream);

        // 统一模板与原图尺寸,避免裁剪错位
        int targetWidth = sourceBitmap.SizeInPixels.Width;
        int targetHeight = sourceBitmap.SizeInPixels.Height;
        if (templateBitmap.SizeInPixels != sourceBitmap.SizeInPixels)
        {
            using (var renderTarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), targetWidth, targetHeight, sourceBitmap.Dpi))
            using (var ds = renderTarget.CreateDrawingSession())
            {
                ds.DrawImage(templateBitmap, new Windows.Foundation.Rect(0, 0, targetWidth, targetHeight));
                templateBitmap = renderTarget;
            }
        }

        // 创建带透明通道的输出渲染目标
        using (var outputRenderTarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), targetWidth, targetHeight, sourceBitmap.Dpi))
        using (var ds = outputRenderTarget.CreateDrawingSession())
        {
            // 基于模板Alpha通道创建遮罩画刷
            var maskBrush = new CanvasImageBrush(CanvasDevice.GetSharedDevice(), templateBitmap)
            {
                ExtendX = CanvasEdgeBehavior.Clamp,
                ExtendY = CanvasEdgeBehavior.Clamp
            };

            // 仅保留原图与模板白色形状重叠的区域
            ds.FillRectangle(new Windows.Foundation.Rect(0, 0, targetWidth, targetHeight), maskBrush);
            ds.DrawImage(sourceBitmap, 0, 0, new Windows.Foundation.Rect(0, 0, targetWidth, targetHeight), 1, CanvasImageInterpolation.HighQuality, CanvasComposite.SourceIn);

            // 将裁剪结果保存到指定路径
            using (var outputStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
            {
                await outputRenderTarget.SaveAsync(outputStream, CanvasBitmapFileFormat.Png);
            }
        }
    }
}

代码说明

  • 尺寸适配:自动将模板缩放至与原图一致,避免裁剪区域错位
  • 遮罩逻辑:通过CanvasComposite.SourceIn混合模式,仅保留原图与模板白色形状重叠的区域,其余区域自动变为透明
  • 异步处理:全程采用异步操作,符合UWP文件访问的规范
  • 高质量渲染:使用CanvasImageInterpolation.HighQuality保证缩放和裁剪后的图像清晰度

使用示例

// 示例:选择文件并调用裁剪函数
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".png");
var sourceFile = await picker.PickSingleFileAsync();
var templateFile = await picker.PickSingleFileAsync();

var savePicker = new Windows.Storage.Pickers.FileSavePicker();
savePicker.SuggestedFileName = "cropped_result";
savePicker.FileTypeChoices.Add("PNG Image", new[] { ".png" });
var outputFile = await savePicker.PickSaveFileAsync();

if (sourceFile != null && templateFile != null && outputFile != null)
{
    await CropImageByTemplateAsync(sourceFile, templateFile, outputFile);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:05:23