C#生成自定义海报

安装包

SixLabors.ImageSharp.Drawing 2.0

C#生成自定义海报_第1张图片
需要的字体:宋体和微软雅黑 商用的需要授权如果商业使用可以使用方正书宋、方正黑体,他们可以免费商用
方正官网

代码

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("完成~~");
        }
    }

    /// 
    /// https://github.com/SixLabors/Samples/blob/main/ImageSharp/AvatarWithRoundedCorner/Program.cs
    /// 
    public static class Helper
    {
        // Implements a full image mutating pipeline operating on IImageProcessingContext
        public 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 square
            var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);

            // Then cut out of the square a circle so we are left with a corner
            IPath 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 shape
            IPath 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);
        }
    }
}

结果

C#生成自定义海报_第2张图片

你可能感兴趣的:(dotnet,c#,开发语言)