如何在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
相关产品推荐
相关产品推荐

