C#生成自定义海报

news2024/11/24 7:30:49

安装包

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 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);
        }
    }
}

结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1048993.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win10默认浏览器改不了怎么办,解决方法详解

win10默认浏览器改不了怎么办&#xff0c;解决方法详解_蓝天网络 在使用Windows 10操作系统时&#xff0c;你可能会遇到无法更改默认浏览器的情况。这可能是因为其他程序或设置正在干扰更改。如果你也遇到了这个问题&#xff0c;不要担心&#xff0c;本文将为你提供详细的解决…

【小笔记】面对一个没搞过的任务,如何选择合适的算法模型?

【学而不思则罔&#xff0c;思而不学则殆】 9.28 1.确定问题定义 确定要解决的问题是一个什么类型&#xff0c;在算法中有没有一个专业的任务名定义它&#xff0c;确定了问题类型就明确了问题解决方向。 有时候我们要解决的问题可能有多种解决问题的角度&#xff0c;此时可能…

Java | CMD命令认识Java

文章目录 1. CMD命令2. Java概念1.1 Java是什么&#xff1f;1.2下载和安装1.2.1 下载1.2.2 安装1.2.3 JDK的安装目录介绍 1.3 Java语言的发展1.4 Java的三大平台1.4.1 JavaSE1.4.2 JavaME1.4.3 JavaEE 1.5 Java的主要特性1.5.1 Java语言跨平台的原理 1.6 Java中认识 JRE 和 JDK…

文明城市美丽乡村随手拍小程序开源版开发

文明城市美丽乡村随手拍小程序开源版开发 拍照功能&#xff1a;用户可以通过小程序直接打开手机相机&#xff0c;拍摄当前所见的城市或乡村美景。 美化照片功能&#xff1a;用户可以在拍摄或选择的照片上进行美化处理&#xff0c;如调整亮度、对比度、饱和度&#xff0c;添加滤…

为什么通配符SSL证书如此受欢迎?

SSL证书是网站安全的重要保障&#xff0c;而通配符SSL证书更是其中的一种。那么&#xff0c;通配符SSL证书有哪些作用呢&#xff1f;为什么通配符SSL证书如此受欢迎呢&#xff1f;下面&#xff0c;我们就来一起探讨一下。 通配符SSL证书的作用有哪些&#xff1f; 通配符SSL证书…

如何管理好公司的公海客户呢?

销售周期比较长&#xff0c;线索处理比较繁琐&#xff0c;想知道用哪些系统可解决这一问题&#xff1f; 很简单&#xff0c;针对客户管理繁杂&#xff0c;线索复杂的问题&#xff0c;crm系统中的公海池就可以轻松解决。 接下来我将以简道云为例为大家进行详细的公海池介绍 ht…

美容店预约小程序搭建流程

随着科技的不断发展&#xff0c;小程序已经成为了人们生活中不可或缺的一部分。对于美容店来说&#xff0c;搭建一个预约小程序不仅可以提高工作效率&#xff0c;还可以增加客户数量、提高服务质量。那么&#xff0c;如何搭建一个美容店预约小程序呢&#xff1f;本文将为你详细…

计算机竞赛 深度学习大数据物流平台 python

文章目录 0 前言1 课题背景2 物流大数据平台的架构与设计3 智能车货匹配推荐算法的实现**1\. 问题陈述****2\. 算法模型**3\. 模型构建总览 **4 司机标签体系的搭建及算法****1\. 冷启动**2\. LSTM多标签模型算法 5 货运价格预测6 总结7 部分核心代码8 最后 0 前言 &#x1f5…

【N年测试总结】区块链行业测试特点

一、区块链业务系统简介 转入转出业务&#xff1a;这类业务一般会涉及币的转入和转出&#xff0c;转入的流程一般是用户从第三方钱包往用户在公司的地址转入&#xff0c;系统收到用户的转入操作消息通知后&#xff0c;定时在链上监控该地址相关的交易&#xff0c;通过校验各项…

20分钟彻底理解Pointpillars论文-妥妥的

PointPillars: Fast Encoders for Object Detection from Point Clouds PointPillars&#xff1a;快就对了 摘要&#xff08;可跳过&#xff09;&#xff1a; 这帮人提出了PointPillars&#xff0c;一种新颖的编码器&#xff0c;它利用PointNets来学习以垂直列组织的点云&am…

LaTex一行排列多个图,并且加入每个图都添加小标题

1、Latex中将字母上下方插入字母数字\mathop{a}\limits_{i1}&#xff1a; a i 1 \mathop{a}\limits_{i1} i1a​ 2Latex罗马数字 大写&#xff1a;\uppercase\expandafter{\romannumeral20} 小写&#xff1a;\romannumeral20 2、LaTex一行排列多个图&#xff0c;并且加入每个…

【轮趣-科大讯飞】M260C 环形六麦测试 1 - 产品介绍与配置

原文发布在飞书上&#xff0c;想要的伙伴请联系我&#xff0c;懒得把飞书链接放这了

RK3568驱动指南|第五期-中断-第47章 工作队列传参实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

微信群发消息如何突破200人?

微信群发怎么设置&#xff1f; 1. 打开微信&#xff0c;点击右下角的“我”&#xff0c;然后选择“设置”。 2. 在设置页面中&#xff0c;选择“通用”选项。 3. 在通用页面中&#xff0c;选择“辅助功能”选项。 4. 在功能页面中&#xff0c;你会看到“群发助手”选项。点…

【Mysql专题】一条SQL在Mysql中是如何执行的

目录 前言前置知识课程内容一、Mysql的内部组件结构1.1 Server层1.2 引擎层&#xff08;Store层&#xff09; 二、连接器三、查询缓存&#xff08;Mysql8.0后已移除&#xff09;四、分析器4.1 词法分析器原理 五、优化器六、执行器学习总结 前言 知其然&#xff0c;当知其所以…

排序:简单选择排序算法分析

选择排序包括简单选择排序以及堆排序。 1.算法分析 每一趟在待排序元素中选取关键字最小的元素加入有序子序列。 n个元素的简单选择排序需要n-1趟处理。 2.代码实现 //交换 void swap(int &a, int &b) {int temp a;a b;b temp; }//简单选择排序 void SelectSort…

定义豪车新理念 远航汽车亮相2023中国(天津)国际汽车展览会

近年来&#xff0c;随着汽车行业竞争持续加剧&#xff0c;老品牌面临积极转型&#xff0c;新势力则经验不足、实力欠佳&#xff0c;到底是难抵市场的风云变幻。在此背景下&#xff0c;有着“老品牌 新势力”双重基因的远航汽车可谓底气十足。作为大运集团携手博世、华为、阿里斑…

nginx 多层代理 + k8s ingress 后端服务获取客户真实ip 配置

1.nginx http 七层代理 修改命令空间&#xff1a; namespace: nginx-ingress : configmap&#xff1a;nginx-configuration kubectl get cm nginx-configuration -n ingress-nginx -o yaml添加如上配置 compute-full-forwarded-for: “true” forwarded-for-header: X-Forwa…

谱瑞PS186|替代PS186方案|TypeC转HDMI4K视频转换方案设计

谱瑞PS186/PS188/PS176,是一系列Type-C/DP转HDMI 4K60的视频转换芯片&#xff0c;其中PS186是DP 2lane转HDMI 4K60&#xff0c;若是设计Type-C转HDMI方案还需加一颗C转DP协议转换芯片&#xff0c;这样成本更高。而集睿致远CS5366单颗芯片即可实现Type-C转HDMI 4K60HZ设计方案. …

python使用mitmproxy和mitmdump抓包以及对手机

mitmproxy是一个中间人角色&#xff0c;供python抓包使用。 本机环境&#xff1a;win10 64位&#xff0c;python3.10.4。首先安装mitmproxy&#xff0c;参考我的文章 记录一下python2和python3在同一台电脑上共存使用并安装各自的库以及各自在pycharm中使用的方法-CSDN博客 一…