安装包
SixLabors.ImageSharp.Drawing 2.0
需要的字体:宋体和微软雅黑 商用的需要授权如果商业使用可以使用方正书宋、方正黑体,他们可以免费商用
方正官网
代码
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;namespace CreatePosterStu01
{internal class Program{static async Task Main(string[] args){//画布宽度int canvasWidth = 750;//画布高度int canvasHeight = 1096;//素材的宽度int posterWidth = 670;//素材的高度int posterHeight = 810;//二维码宽度int qrCodeWidth = 140;//二维码高度int qrCodeHeight = 140;//头像宽度和高度int avatorWidth = 110;int avatorHeight = 110;//昵称var nickName = "假装wo不帅";//签名,个性签名var diySign = "\"这个真不错,推荐你也来看看啊啊啊sdf\"";var imgName = $"{DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")}.png";using (Image<Rgba32> image = new Image<Rgba32>(canvasWidth, canvasHeight, Color.White)){//绘制顶部图片var topImage = Image.Load("images/main.jpg");//也可以加载stream//var qrCodeImage = Image.Load(data);//改变显示区域的大小,并不能改变图片大小//var posterRect = new Rectangle(0,0, posterWidth, posterHeight);//image.Mutate(t => t.DrawImage(topImage, new Point(40, 40), posterRect, 1f));//存放海报位置//KnownResamplers.Bicubic 获取实现双三次核算法W(x)的双三次采样器//KnownResamplers.Box 获取实现盒算法的盒采样器。类似于升级时的最近邻居。缩小像素时,会对像素进行平均,将像素合并在一起。topImage.Mutate(x => x.Resize(posterWidth, posterHeight, KnownResamplers.Box));image.Mutate(t => t.DrawImage(topImage, new Point(40, 40), 1f));//存放二维码var qrcodeImage = Image.Load("images/qrcode.jpg");qrcodeImage.Mutate(x => x.Resize(qrCodeWidth, qrCodeHeight, KnownResamplers.Box));image.Mutate(t => t.DrawImage(qrcodeImage, new Point(560, 900), 1f));//存放头像var avatorImage = Image.Load("images/avator.jpg");//转化为圆角,此时有黑色边框avatorImage.Mutate(x => x.Resize(avatorWidth, avatorHeight));//avatorImage.Mutate(x => x.ConvertToAvatar(new Size(avatorWidth, avatorHeight), (avatorWidth / 2.0f)));image.Mutate(t => t.DrawImage(avatorImage, new Point(40, 915), 1f));//显示昵称FontCollection fonts = new FontCollection();var songtiFamily = fonts.Add("fonts/simsun.ttf");var yaheiFamily = fonts.Add("fonts/weiruanyahei.ttf");image.Mutate(t => t.DrawText(nickName, new Font(yaheiFamily, 15 * 2, FontStyle.Bold), Color.ParseHex("#000000"), new PointF(160, 940)));//显示签名//判断长度决定是否显示...,目前一行最多16个字,超出部分显示...if (diySign.Length > 16){diySign = diySign.Remove(15, diySign.Length - 15) + "...";}image.Mutate(t => t.DrawText(diySign, new Font(yaheiFamily, 13 * 2, FontStyle.Bold), Color.ParseHex("#cccccc"), new PointF(160, 985)));var fileStream = File.Create(imgName);await image.SaveAsync(fileStream, new PngEncoder());//也可以保存为文件流,web端使用/*using (var stream = new MemoryStream()){await image.SaveAsync(stream, new PngEncoder());stream.Position = 0; return stream;}*/}await Console.Out.WriteLineAsync("完成~~");}}/// <summary>/// https://github.com/SixLabors/Samples/blob/main/ImageSharp/AvatarWithRoundedCorner/Program.cs/// </summary>public static class Helper{// Implements a full image mutating pipeline operating on IImageProcessingContextpublic static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext context, Size size, float cornerRadius){return context.Resize(new ResizeOptions{Size = size,Mode = ResizeMode.Crop}).ApplyRoundedCorners(cornerRadius);}// This method can be seen as an inline implementation of an `IImageProcessor`:// (The combination of `IImageOperations.Apply()` + this could be replaced with an `IImageProcessor`)private static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext context, float cornerRadius){Size size = context.GetCurrentSize();IPathCollection corners = BuildCorners(size.Width, size.Height, cornerRadius);context.SetGraphicsOptions(new GraphicsOptions(){Antialias = true,// Enforces that any part of this shape that has color is punched out of the background//强制将此形状中任何有颜色的部分从背景中冲压出来AlphaCompositionMode = PixelAlphaCompositionMode.DestOut});// Mutating in here as we already have a cloned original// use any color (not Transparent), so the corners will be clipped//在这里突变,因为我们已经有了一个克隆的原始使用任何颜色(非透明),所以角将被剪切foreach (IPath path in corners){context = context.Fill(Color.Red, path);}return context;}private static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius){// First create a squarevar rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);// Then cut out of the square a circle so we are left with a cornerIPath cornerTopLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));// Corner is now a corner shape positions top left// let's make 3 more positioned correctly, we can do that by translating the original around the center of the image.float rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1;float bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1;// Move it across the width of the image - the width of the shapeIPath cornerTopRight = cornerTopLeft.RotateDegree(90).Translate(rightPos, 0);IPath cornerBottomLeft = cornerTopLeft.RotateDegree(-90).Translate(0, bottomPos);IPath cornerBottomRight = cornerTopLeft.RotateDegree(180).Translate(rightPos, bottomPos);return new PathCollection(cornerTopLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);}}
}