NetCore使用SixLabors组件生成图片

主要用到SixLabors.Fonts(2.1.0)和SixLabors.ImageSharp.Drawing(2.1.0)组件

这里我把组件创建成一个单独的类库,供其他模块来同意调用

ISixLaborsExtensions.cs

using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Processing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace Tzkj.SixLabors
{
    public interface ISixLaborsExtensions
    {
        /// <summary>
        /// 生成会员证书
        /// </summary>
        /// <param name="numX"></param>
        /// <param name="numY"></param>
        /// <param name="nameX"></param>
        /// <param name="nameY"></param>
        /// <param name="yearX"></param>
        /// <param name="yearY"></param>
        /// <param name="mounthX"></param>
        /// <param name="mounthY"></param>
        /// <param name="DayX"></param>
        /// <param name="DayY"></param>
        /// <returns></returns>
        Task<SixLaborOptions> GenerateMembershipCertificateAsync(string companyName, string orderNo, bool isAdd = true, int numX = 700, int numY = 560, int nameX = 540, int nameY = 665, int yearX = 1488, int yearY = 1155,
            int mounthX = 1612, int mounthY = 1155, int DayX = 1706, int DayY = 1155);
    }
}

SixLaborsExtensions.cs

using Org.BouncyCastle.Asn1;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Processing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tzkj.Core.Constants;
using Tzkj.Core.System;
using Volo.Abp.DependencyInjection;

namespace Tzkj.SixLabors
{
    public class SixLaborsExtensions : ISixLaborsExtensions, IScopedDependency
    {
        private readonly FontCollection _fontCollection;

        public SixLaborsExtensions(FontCollection fontCollection)
        {
            _fontCollection = fontCollection;
        }


        /// <summary>
        /// 生成会员证书
        /// <paramref name="companyName">名称</param>
        /// <param name="numX"></param>
        /// <param name="numY"></param>
        /// <param name="nameX"></param>
        /// <param name="nameY"></param>
        /// <param name="yearX"></param>
        /// <param name="yearY"></param>
        /// <param name="mounthX"></param>
        /// <param name="mounthY"></param>
        /// <param name="DayX"></param>
        /// <param name="DayY"></param>
        /// <returns></returns>
        public async Task<SixLaborOptions> GenerateMembershipCertificateAsync(string companyName, string orderNo,
            bool isAdd = true,
            int numX = 700, int numY = 560, int nameX = 540, int nameY = 665, int yearX = 1488, int yearY = 1155,
            int mounthX = 1612, int mounthY = 1155, int DayX = 1706, int DayY = 1155)
        {
            using var img = await Image.LoadAsync("wwwroot/robotMember.jpg");
            _fontCollection.TryGet("FangSong", out FontFamily fontFamily);
            string? numberNo = orderNo;
            using var img2 = img.Clone(ctx => ApplyScalingWaterMarkRobot(ctx, fontFamily, Color.Black,
                companyName, orderNo, isAdd, out numberNo, numX, numY, nameX, nameY, yearX, yearY, mounthX, mounthY, DayX, DayY));
            using var memoryStream = new MemoryStream();
            await img2.SaveAsJpegAsync(memoryStream);
            var tt = memoryStream.ToArray();

            return new SixLaborOptions
            {
                ImgBytes = tt,
                CertificateNo = numberNo
            };
        }

        private IImageProcessingContext ApplyScalingWaterMarkRobot(IImageProcessingContext processingContext,
            FontFamily fontFamily, Color color, string companyName, string orderNo, bool isAdd, out string numberNo, int numX = 494, int numY = 528, int nameX = 450, int nameY = 650, int yearX = 650, int yearY = 736,
            int mounthX = 896, int mounthY = 736, int DayX = 990, int DayY = 736)
        {
            var numPoint = new PointF(numX, numY);
            Font numFont = fontFamily.CreateFont(38);
            var numTextOptions = new RichTextOptions(numFont)
            {
                Origin = numPoint
            };
            //processingContext.DrawText(numTextOptions, "HRES20231225001", color);
            numberNo = orderNo;
            if (isAdd)
            {

//参考地址:C# 生成订单号-CSDN博客
                numberNo = GenerateOrderNo.Gener(orderNo,SystemConstants.MemberCardPrefix);
            }

            processingContext.DrawText(numTextOptions, numberNo, color);

            var namePoint = new PointF(nameX, nameY);
            Font nameFont = fontFamily.CreateFont(48);
            var nameTextOptions = new RichTextOptions(nameFont)
            {
                Origin = namePoint
            };
            processingContext.DrawText(nameTextOptions, companyName, color);

            var yearPoint = new PointF(yearX, yearY);
            var monthPoint = new PointF(mounthX, mounthY);
            var dayPoint = new PointF(DayX, DayY);
            Font dateFont = fontFamily.CreateFont(38);

            processingContext
                .DrawText(
                    new RichTextOptions(dateFont)
                    {
                        Origin = yearPoint
                    },
                    "2023",
                    color)
                .DrawText(
                    new RichTextOptions(dateFont)
                    {
                        Origin = monthPoint
                    },
                    "06",
                    color)
                .DrawText(
                    new RichTextOptions(dateFont)
                    {
                        Origin = dayPoint
                    },
                    "26",
                    color);

            return processingContext;
        }
    }
}

SixLaborsModule.cs

using Microsoft.Extensions.DependencyInjection;
using SixLabors.Fonts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Modularity;

namespace Tzkj.SixLabors
{
    public class SixLaborsModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            //var configuration = context.Services.GetConfiguration();

            //图片合成组件单例注入
            context.Services.AddSingleton<FontCollection>(serviceProvider =>
            {
                FontCollection fontCollection = new();
                fontCollection.Add("./wwwroot/Fonts/simfang.ttf");
                //fontCollection.Add(configuration["SixLabors:FontsPath"]);
                return fontCollection;
            });
        }
    }
}

SixLaborOptions.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tzkj.SixLabors
{
    public class SixLaborOptions
    {
        /// <summary>
        /// 证书编号
        /// </summary>
        public string CertificateNo { get; set; }

        /// <summary>
        /// 二进制图片
        /// </summary>
        public byte[] ImgBytes { get; set; }
    }
}

controller.cs

        /// <summary>
        /// 获取会员证书
        /// </summary>
        /// <param name="id">企业id</param>
        /// <returns></returns>
        [HttpGet("get-memberCard")]
        public async Task<IActionResult> GetMemberCardUrlAsync(Guid id)
        {
            byte[] bytes = await _companyInfoService.GetMemberCardUrlAsync(id);
            var qualification = File(bytes, "image/jpeg");

            return qualification;
        }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【算法Hot100系列】搜索旋转排序数组

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

[AutoSar]基础部分 RTE 05 Port的实例化和初始化

目录 关键词平台说明一、端口类型二、端口的实例化2.1 创建application port2.2 实例化 三、初始化 关键词 嵌入式、C语言、autosar、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、端口类型 如下图所示&am…

一种DevOpts的实现方式:基于gitlab的CICD(一)

写在之前 笔者最近准备开始入坑CNCF毕业的开源项目&#xff0c;看到其中有一组开源项目的分类就是DevOpts。这个领域内比较出名的项目是Argocd&#xff0c;Argo CD 是一个用于 Kubernetes 的持续交付 (Continuous Delivery) 工具&#xff0c;它以声明式的方式实现了应用程序的…

scipy-interpolate整理

文章目录 scipy-interpolate整理Univariate interpolation 单变量插值Multivariate interpolation 多元插值Unstructured data 非结构化数据&#xff1a;:For data on a grid 对于网格上的数据&#xff1a;:Tensor product polynomials 张量积多项式&#xff1a;: 1-D Splines …

Windows更新 遇到错误 你的设备中缺少重要的安全和质量修复 0x80070643问题解决

一、原因 日常Windows更新时&#xff0c;突然出现以下错误&#xff1a; 二、最简单的方法 官方网址windows10升级工具进行更新&#xff1a;https://www.microsoft.com/zh-cn/software-download/windows10/   更新助手可以帮助你更新到 Windows 10 的最新版本&#xff0c…

【刷题日记】青少年CTF-Misc(三)A1-Misc部分完结!撒花!

StegoTXT 题目难度&#xff1a;★ 题目编号&#xff1a;QSNCTF-2023-T-MISC-20230228003 题目描述&#xff1a;今天维护网站的时候出了一道这样的题目&#xff0c;上传上来看看大家怎么解&#xff0c;flag格式为&#xff1a;qsnctf{xxx}。 下载解压文件&#xff0c;得到一个…

海淘注意事项科普

关税和税费&#xff1a; 在海淘过程中&#xff0c;您可能需要支付关税和其他税费。了解目标国家的相关规定&#xff0c;预先了解可能的费用&#xff0c;并确保考虑到这些额外成本。 货币汇率&#xff1a; 注意货币汇率的波动&#xff0c;以避免因兑换率变化导致支付更多费用。…

嵌入式-C语言-江科大-指针的详解与应用

文章目录 一&#xff1a;计算机存储机制二&#xff1a;定义指针三&#xff1a;指针的操作四&#xff1a;数组与指针五&#xff1a;指针的应用道友&#xff1a;最清晰的脚印&#xff0c;踩在最泥泞的道路上。 推荐视频配合我的笔记使用 [C语言] 指针的详解与应用-理论结合实践&a…

Flask修改Response Headers中的Server值

Headers中的Server会暴露出Python版本&#xff0c;导致的结果就是方便被渗透快速定位Python版本后找到对应版本的漏洞&#xff0c;因此导致网络安全问题 伪方法&#xff1a; 像这个马上就暴露出Python版本&#xff0c;如何解决这个网络上有说直接用response.headers.remove(Ser…

Windows内存管理(二):内存架构 浅谈一二

《Windows内存管理&#xff08;一&#xff09;&#xff1a;Windows性能监视器(PerfMon)》 Windows内存管理是一个复杂的主题&#xff0c;涉及多个层次和组件。以下是一个分层的概述。 1、虚拟内存管理 Windows使用虚拟内存来给每个进程提供一个看似连续的内存空间&#xff0c…

Java学习笔记-day01-Flowable工作流入门

课程来源B站大佬波哥的课程 本文仅做笔记&#xff0c;课件需要的联系B站大佬获取 0.前置 相关话术 流程定义&#xff08;Process Definition&#xff09;&#xff1a; 描述业务流程的定义&#xff0c;通常使用BPMN&#xff08;Business Process Model and Notation&#xff09…

没有货源是不是就没办法在家做抖店?打包发货怎么完成?解答如下

我是王路飞。 有人问了我一个问题&#xff1a;无货源模式的抖店&#xff0c;自己一个人在家里做不了是吧&#xff1f;毕竟打包发货这些问题怎么解决呢&#xff1f; 店铺要是发货不及时被平台罚款怎么办&#xff1f;产品有质量问题怎么解决呢&#xff1f;店铺一直不出单怎么办…

并发程序设计--D5~D7线程的创建、回收和取消清理

一个进程中的多个线程共享以下资源 可执行指令 静态数据 进程中打开的文件描述符 当前工作目录 用户ID 用户组ID 每个线程私有的资源 线程ID PC&#xff08;程序计数器&#xff09;和相关寄存器 堆区和栈区 错误号&#xff08;errno&#xff09; 优先级 执行状态和属性 线程的…

2024阿里云服务器ECS实例全方位介绍_优缺点大全

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网aliyu…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -用户信息修改实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

数字化解决方案在市政交通大显身手

Bentley 应用程序促进了创新设计解决方案&#xff0c;预计可在 25 年内节省 3,200 万美元 大规模现代化计划 大学大道位于爱荷华州锡达福尔斯市繁忙的社区&#xff0c;是一条重要的六车道高速公路&#xff0c;长约两英里&#xff0c;每天通行的车辆有 2 万多辆。该道路已有 60…

java编程中,保证接口幂等性的实现方案讨论

一、什么是幂等性 数学中的幂等是指f(x) f(f(x))&#xff0c;编程领域的术语是指同一个操作&#xff0c;在重复提交的情况下&#xff0c;最终产生的影响是不变的。举例说&#xff1a; 提交订单时&#xff0c;用户在购物车界面&#xff0c;重复点击“下单”&#xff0c;服务端…

vxe-树形结构层级过多横向滚动条设置

一. 问题 在使用vxe-table中的树形结构的时候&#xff0c;如果树形结构的层级过多的话的会导致层级很深的层级&#xff0c;鼠标点击无法选中&#xff0c;对应的内容显示不完全。 层级过多后 二. 解决 方法1&#xff1a;动态的计算所占行的宽度&#xff0c;选取最大宽度给表格列…

统信UOS虚拟机安装VirtualBox扩展使用USB功能

为什么要安装VirtualBox扩展包&#xff1f; 安装 Oracle VM VirtualBox 扩展包的原因是&#xff0c;它提供了对 USB 2.0、USB 3.0、远程桌面协议 VRDP&#xff08;VirtualBox Remote Desktop Protocol&#xff09;等实用功能的支持&#xff0c;以增强 VirtualBox 的功能。这些…

MIT_线性代数笔记:第 25 讲 对称矩阵和正定性

目录 对称矩阵 Symmetric matrices实特征值 Real eigenvalues正定矩阵 Positive definite matrices 对称矩阵是最重要的矩阵之一&#xff0c;其特征值为实数并且拥有一套正交特征向量。正定矩阵的性质则更好。 对称矩阵 Symmetric matrices 包含特殊性质的矩阵&#xff0c;例如…