在Xamarin.Forms中用代码创建及叠加图像的技术问询
Great question! Since System.Drawing is indeed limited in .NET Standard 2.0 (especially for cross-platform compatibility), the best alternative here is SkiaSharp—a .NET binding for Google's Skia graphics library. It fully supports .NET Standard 2.0, works across all major platforms, and has all the tools you need to build everything from basic blank images to sports-channel-style overlays.
First, install the SkiaSharp NuGet package to get started:
# Package Manager Console Install-Package SkiaSharp # .NET CLI dotnet add package SkiaSharp
Let’s walk through each of your requirements with concrete code examples:
1. 创建蓝色背景图并添加红色线条与文字
这个示例生成一张200×200的蓝色背景图,添加一条粗红色水平线,并在中心位置放置白色文字:
using SkiaSharp; using System.IO; // 初始化200×200的位图,填充蓝色背景 using var bitmap = new SKBitmap(200, 200); using var canvas = new SKCanvas(bitmap); canvas.Clear(SKColors.Blue); // 绘制粗红色水平线 using var redLinePaint = new SKPaint { Color = SKColors.Red, StrokeWidth = 5, Style = SKPaintStyle.Stroke }; canvas.DrawLine(0, 100, 200, 100, redLinePaint); // 添加居中的白色文字 using var textPaint = new SKPaint { Color = SKColors.White, TextSize = 24, IsAntialias = true, TextAlign = SKTextAlign.Center }; // 计算文字垂直居中的偏移量 var textBounds = new SKRect(); textPaint.MeasureText("Hello SkiaSharp", ref textBounds); var verticalOffset = textBounds.Height / 2; canvas.DrawText("Hello SkiaSharp", bitmap.Width / 2, bitmap.Height / 2 + verticalOffset, textPaint); // 将最终图像保存为PNG文件 using var image = SKImage.FromBitmap(bitmap); using var imageData = image.Encode(SKEncodedImageFormat.Png, 100); using var outputStream = File.OpenWrite("blue_background.png"); imageData.SaveTo(outputStream);
2. 制作体育频道风格的条纹标识
这个示例创建一个带透明背景的红白条纹标识,叠加加粗文字,为后续的图像叠加做准备:
using SkiaSharp; using System.IO; // 创建150×50的带透明通道的位图(预乘Alpha确保透明度正常) using var badgeBitmap = new SKBitmap(150, 50, SKColorType.Rgba8888, SKAlphaType.Premul); using var badgeCanvas = new SKCanvas(badgeBitmap); // 绘制半透明的红白交替条纹 var stripeHeight = 10; for (int y = 0; y < badgeBitmap.Height; y += stripeHeight * 2) { // 红色条纹(86%不透明度) using var redStripePaint = new SKPaint { Color = SKColors.Red.WithAlpha(220) }; badgeCanvas.DrawRect(0, y, badgeBitmap.Width, stripeHeight, redStripePaint); // 白色条纹(86%不透明度) using var whiteStripePaint = new SKPaint { Color = SKColors.White.WithAlpha(220) }; badgeCanvas.DrawRect(0, y + stripeHeight, badgeBitmap.Width, stripeHeight, whiteStripePaint); } // 在标识中心添加加粗的"SPORT"文字 using var badgeTextPaint = new SKPaint { Color = SKColors.Black, TextSize = 20, IsAntialias = true, TextAlign = SKTextAlign.Center, Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold) }; badgeCanvas.DrawText("SPORT", badgeBitmap.Width / 2, badgeBitmap.Height / 2 + 8, badgeTextPaint); // 将透明标识保存为PNG文件 using var badgeImage = SKImage.FromBitmap(badgeBitmap); using var badgeData = badgeImage.Encode(SKEncodedImageFormat.Png, 100); using var badgeStream = File.OpenWrite("sports_badge.png"); badgeData.SaveToStream(badgeStream);
3. 透明标识与实际图像的叠加
这个示例加载一张现有照片,将制作好的条纹标识叠加到右上角,同时保留标识的透明效果:
using SkiaSharp; using System.IO; // 加载基础图像(比如一张体育照片) using var baseBitmap = SKBitmap.Decode("sports_photo.jpg"); using var canvas = new SKCanvas(baseBitmap); // 加载之前创建的透明标识 using var badgeBitmap = SKBitmap.Decode("sports_badge.png"); // 设置标识位置:右上角,距离边缘10px var overlayX = baseBitmap.Width - badgeBitmap.Width - 10; var overlayY = 10; // 将标识绘制到基础图像上(自动处理透明层) canvas.DrawBitmap(badgeBitmap, overlayX, overlayY); // 保存最终的叠加图像 using var finalImage = SKImage.FromBitmap(baseBitmap); using var finalData = finalImage.Encode(SKEncodedImageFormat.Jpeg, 90); using var finalStream = File.OpenWrite("sports_photo_with_badge.jpg"); finalData.SaveToStream(finalStream);
为什么选择SkiaSharp?
- 跨平台兼容: 支持Windows、Linux、macOS、移动设备等所有主流平台,这是.NET Standard下System.Drawing不具备的特性。
- API易上手: 如果你熟悉System.Drawing的画布式API,SkiaSharp的语法逻辑会非常直观,迁移成本低。
- 原生支持透明: 完美处理Alpha通道,半透明元素叠加无需额外处理。
- 活跃维护: 由Google和.NET社区共同维护,持续更新且文档完善。
你之前用System.Drawing实现的条纹绘制逻辑,只需要简单调整API就能在SkiaSharp中复用,比如将Graphics替换为SKCanvas,Brushes替换为SKPaint即可。
内容的提问来源于stack exchange,提问作者Joe Johnston

