Net6 用imagesharp 实现跨平台图片处理并存入oss

news2024/11/27 0:19:19

项目要求:生成电子证书

一、模板文件在OSS中,直接加载

二、向模板文件添加二维码

三、向模板文件添加多行文字

四、生成二维码,存入本地,

五、向模板文件添加二维码

代码实现步骤

一、建立.net 6 API项目,安装Nuget包

TestImageShapForNet6API

二、配置好OSS的相关功能,包括OSS绑定域名,配置SSL证书等,保证模板文件可以以URL的模式显示在浏览器中

http://oss.crabstech.com/code/21122504.jpg

获取OSS的AK信息和存储权限,以保证文件的正常读取和存入

三、创建内容行的model

using SixLabors.Fonts;

namespace TestImageShapForNet6API
{
    public class DrawContent
    {
        public int x { get; set; } 

        public int y { get; set; } 

        public Font font { get; set; } = null!;

        public string Text { get; set; } = null!;

        public Color color { get; set; } = Color.Black;
    }
}

四、创建OSS处理类(阿里云OSS ,具体文档请参考阿里云)

using Aliyun.OSS;

namespace TestImageShapForNet6API
{
    public class OssHandle
    {
        const string Endpoint = "oss-cn-zhangjiakou.aliyuncs.com";
        const string AccessKeyId = "你的keyId";
        const string AccessKeySecret = "你的keysecret";
        const string BucketName = "你的bucketname";
        const string DirName = "自己起的目录名";
        const string Url = "你自己的bucket绑定的域名";


        public string PutImg2Oss(byte[] image,string objName)
        {

            var _img = new MemoryStream(image);

            var client = new OssClient(Endpoint,AccessKeyId, AccessKeySecret);

            try
            {
                var res = client.PutObject(BucketName, $"{DirName}/{objName}", _img);
                Console.WriteLine(res.ToString);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return $"{Url}{DirName}/{objName}";

        }
    }
}

五、生成二维码

using ZXing.QrCode;
using ZXing;

namespace TestImageShapForNet6API
{
    public class QrFile
    {
        public async Task<string> Output(string text)
        {
            var basePath = AppContext.BaseDirectory;
            
            var filePath = Path.Combine(basePath, $"images/qr.jpg");
            
            //生成二维码
            var writer = new ZXing.ImageSharp.BarcodeWriter<Rgba32>
            {
                Format = BarcodeFormat.QR_CODE,
                Options = new QrCodeEncodingOptions
                {
                    Width = 400,
                    Height = 400,
                    Margin = 2,

                }

            };
            var image = writer.WriteAsImageSharp<Rgba32>(text);
            await image.SaveAsync(filePath);
            Console.WriteLine("Image success");
            return filePath;
        }
    }
}

六、创建合并方法,和调用方法。注意:“/”的问题,windows下对"/"和"\"容忍度比较高,怎么写基本都可以找到路径。但linux下一定要写 "/",否则会找不到文件

using SixLabors.Fonts;
using SixLabors.ImageSharp.Drawing.Processing;
using System.Net;

namespace TestImageShapForNet6API
{
    public class MergeImg
    {
        
        /// <summary>
        /// 图片上写字
        /// https://docs.sixlabors.com/articles/imagesharp.drawing/gettingstarted.html#expanded-example
        /// </summary>
        /// <param name="ImagePath"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="txt"></param>
        /// <param name="fontPath"></param>
        /// <returns></returns>
        private Image? drawingTextOnImage(string url, string qrImgPath, List<DrawContent> contList)
        {

            if (string.IsNullOrWhiteSpace(url) || contList is null || contList.Count < 1)
                return null;

            // 线上地址的图片,通过获取流的方式读取   
            WebRequest imgRequest = WebRequest.Create(url);
            var res = (HttpWebResponse)imgRequest.GetResponse();

            // 加载图片
            var image = Image.Load(res.GetResponseStream());

            // 按行向图片写入文字
            foreach (var item in contList)
            {
                PointF point = new PointF(item.x, item.y);
                image.Mutate(x => x.DrawText(item.Text, item.font, item.color, point));
            }



            // 加载二维码图片
            var qrImg = Image.Load(qrImgPath);

            // 向图片上添加二维码
            image.Mutate(x => x.DrawImage(qrImg, new Point(1650, 3600), 1));


            return image;
        }

        public async Task<string> DrawingTextOnImage()
        {
            var basePath = AppDomain.CurrentDomain.BaseDirectory;            
            var url = "http://oss.crabstech.com/code/21122504.jpg";
            var qrImgPath = $"{basePath}images/qr.jpg";
            var imgPath = $"{basePath}images/temp.jpg";


            var contList = new List<DrawContent>();

            var _first = new DrawContent
            {
                x = 600,
                y = 1600,
                Text = "张小斐",
                font = SystemFonts.CreateFont("SimHei", 160, FontStyle.Regular),
                color = Color.Green
                

            };
            contList.Add(_first);

            var img = drawingTextOnImage(url, qrImgPath, contList);
            var ms = new MemoryStream();
            
            img.SaveAsJpeg(ms);
            Console.WriteLine("生成成功");
            var _imgMs = ms.ToArray();

            var ossHandler = new OssHandle();
            var result = await Task.Run(()=>{
                return ossHandler.PutImg2Oss(_imgMs, "code-01.jpg");
            });

            return result;
        }
    }
}

七、创建controller ,调用方法实现

完整的program.cs

using TestImageShapForNet6API;

var builder = WebApplication.CreateBuilder(args);

var basePath = AppContext.BaseDirectory;
builder.Services.AddControllers();


// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();


app.UseStaticFiles();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
   
}
app.UseSwagger();
app.UseSwaggerUI();

app.MapGet("/qrcode", async () => {
    var _qr = new QrFile();
    return await _qr.Output("http://oss.crabstech.com/han/6d9a492bf72f4dc2bf59154c8c603c85_2.png");
})
.WithName("QrCode");

app.MapGet("/merimg", async () =>
{
    var img = new MergeImg();
    return await img.DrawingTextOnImage();
})
.WithName("MergeImg");

app.Run();

本地启动

先调用一次qrcode,再调用一次merimg。(只是为了测试两个API都可以单独使用,实际项目中请按照正常逻辑布署)

执行后我们得到了oss的Url地址:https://oss.crabstech.com/code/code-01.jpg

将地址粘贴到浏览器,得到已合成的图片文件

八、添加DockerFile

在项目中添加fonts文件夹,从c:\windows\fonts中拷贝基础的几个字体文件到项目的fonts中

在项目上点右键

 

 此时生成Dockerfile文件

 点击Dockerfile编辑

#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80

#设置时间为中国上海
ENV TZ=Asia/Shanghai
ENV DEBIAN_FRONTEND noninteractive

 

# 设置包源为阿里
RUN  sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g  /etc/apt/sources.list \
&& apt-get clean

# 安装 tzdata 软件包
RUN apt-get update \
&& apt-get install -y tzdata \
&& ln -fs /usr/share/zoneinfo/$TZ  /etc/localtime \
&& rm -rf /var/lib/apt/lists/ \
&& dpkg-reconfigure -f noninteractive tzdata

# 安装字体 注意:“/”的问题,windows下对"/"和"\"容忍度比较高,怎么写基本都可以找到路径。但linux下一定要写 "/",否则会找不到文件
COPY ["TestImageShapForNet6API/fonts/ARIAL.TTF","/usr/share/fonts/ttf-dejavu/ARIAL.TTF"]
COPY ["TestImageShapForNet6API/fonts/SIMFANG.TTF","/usr/share/fonts/ttf-dejavu/SIMFANG.TTF"]
COPY ["TestImageShapForNet6API/fonts/SIMHEI.TTF","/usr/share/fonts/ttf-dejavu/SIMHEI.TTF"]
COPY ["TestImageShapForNet6API/fonts/SIMKAI.TTF","/usr/share/fonts/ttf-dejavu/SIMKAI.TTF"]
COPY ["TestImageShapForNet6API/fonts/SIYUANSONGTI.TTF","/usr/share/fonts/ttf-dejavu/SIYUANSONGTI.TTF"]



FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["TestImageShapForNet6API/TestImageShapForNet6API.csproj", "TestImageShapForNet6API/"]
RUN dotnet restore "TestImageShapForNet6API/TestImageShapForNet6API.csproj"
COPY . .
WORKDIR "/src/TestImageShapForNet6API"
RUN dotnet build "TestImageShapForNet6API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "TestImageShapForNet6API.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .




ENTRYPOINT ["dotnet", "TestImageShapForNet6API.dll"]

再次点击右键,选择容器业务流程协调程序

 点击编辑

 

version: '3.4'

services:
  testimageshapfornet6api:
    image: imagehandle:20231012.01
    build:
      context: "./TestImageShapForNet6API"
      dockerfile: "./TestImageShapForNet6API/Dockerfile"
    container_name: "imagehandle"
    ports: 
        - 20205:80 
        - 20206:443
    volumes:
      - "./config/appsettings.json:/app/appsettings.json" 
      
      
    environment:
        - ASPNETCORE_ENVIRONMENT=Production
    restart: always 

这里注意以下三点

 

至此在本地要准备的内容准备完毕

下面是在宝塔中操作的内容

一、在文件中找个地方创建个文件夹,一般放在以下这个地方

 

创建并打开文件夹,将项目文件压缩为zip后上传(压缩前记得编译生成一次),压缩时要选择最项目最外层文件夹,保证zip文件完整性

将文件上传到文件夹下,进行解压缩。

并且在该文件夹下建立config文件,将项目的appsetting.json拷贝到config下

将docker-compose.yml文件,拷贝到该目录下

解压拷贝完成后的目录状态如下

 

在该目录下的终端里,执行部署 

docker-compose -f docker-compose.yml up

发布成功,是这样的 

 

此时可以关闭这个终端,开一个新的终端查看

docker ps

或者在宝塔的Docker中查看

下面需要建立网站来映射docker

在宝塔中正常添加网站,绑定域名

然后修改配置文件

server
{
    listen 80;
    server_name 你的域名(确保已经解析到当前服务器了);
    index index.html index.htm index.aspx ;
    location / {

                proxy_pass http://localhost:20205; #这里的端口号就是docker发布时,左侧的端口号
        }
   
}

至此项目发布完毕

如果此时访问域名,显示404,不要慌,在域名后添加/swagger/index.html

即:http://你的域名/swagger/index.html

在oss中查看文件存储的时间,确定是刚刚生成无误

至此项目需求完成

项目下载地址

在.net 6下用SixLabors.ImageSharp实现图片跨平台处理icon-default.png?t=N7T8https://gitee.com/shirleycat/image-sharp-for-net6-api

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

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

相关文章

SpringBoot-黑马程序员-学习笔记(五)

74.自定义bean属性绑定以及第三方bean属性绑定 自定义bean属性绑定 1.自定义一个bean Data Component public class ServerConfig {private String ipAddress;private int port;private long timeout; } 2.在yml配置文件中中定义一组值 3.在bean中进行属性绑定 加上这个注…

【Linux】:Linux环境与版本

以下哪个命令输出Linux内核的版本信息 A.uname -r B.vmstat C.sar D.stat uname -r 查看linux内核版本信息 vmstat 报告关于内核线程、虚拟内存、磁盘、陷阱和 CPU 活动的统计信息 sar 主要帮助我们掌握系统资源的使用情况&#xff0c;特别是内存和CPU的使用情况 stat 用于显示…

【从零开始学习Redis | 第二篇】Redis中的数据类型和相关命令

前言&#xff1a; Redis是一种快速、高效的开源内存数据库&#xff0c;被广泛用于构建各种类型的应用程序。其被设计成支持多种数据类型&#xff0c;这使得Redis在处理各种场景的数据存储和操作中非常灵活。Redis的数据类型提供了对不同数据结构的直接支持&#xff0c;包括字符…

并查集维护集合 ac240食物链

题目&#xff1a; 代码&#xff1a; #include<iostream> using namespace std; const int N50010; int p[N],d[N]; int n,m;int find(int x){if(p[x]!x){ int ufind(p[x]);d[x] d[p[x]];p[x]u;}return p[x]; }int main(){scanf("%d%d",&n,&m);fo…

Java设计模式之六大设计原则

为什么要学习设计模式&#xff1f; 要知道设计模式就是软件工程的方法经验的总结&#xff0c;也是可以认为是过去一段时间软件工程的一个最佳实践&#xff0c;要理解&#xff0c;不要死记硬背。掌握这些方法后&#xff0c;可以让你的程序获得以下好处&#xff1a; 代码重用性…

SpringCloud-Hystrix

一、介绍 &#xff08;1&#xff09;避免单个服务出现故障导致整个应用崩溃。 &#xff08;2&#xff09;服务降级&#xff1a;服务超时、服务异常、服务宕机时&#xff0c;执行定义好的方法。&#xff08;做别的&#xff09; &#xff08;3&#xff09;服务熔断&#xff1a;达…

学习记忆——题型篇——写作——记忆宫殿法

1&#xff0e;什么是数字记忆法? 答&#xff1a; 数字记忆就是把每一个数字转换成图片编码后再进行联想速记。 2&#xff0e;数字记忆法的用途有哪些&#xff1f; 答&#xff1a; 可以记忆学科知识&#xff0c;如地理、历史等所有学科或考试中的数据信息&#xff1b;可以速记生…

给ChuanhuChatGPT 配上讯飞星火spark大模型V2.0(一)

ChuanhuChatGPT 拥有多端、比较好看的Gradio界面&#xff0c;开发比较完整&#xff1b; 刚好讯飞星火非常大气&#xff0c;免费可以领取大概20w&#xff08;&#xff01;&#xff01;&#xff01;&#xff09;的token&#xff0c;这波必须不亏&#xff0c;整上。 重要参考&am…

中断机制-中断协商机制、中断方法

4.1 线程中断机制 4.1.1 从阿里蚂蚁金服面试题讲起 Java.lang.Thread下的三个方法: 4.1.2 什么是中断机制 首先&#xff0c;一个线程不应该由其他线程来强制中断或停止&#xff0c;而是应该由线程自己自行停止&#xff0c;自己来决定自己的命运&#xff0c;所以&#xff0c;…

创意无限,动画随心——Adobe Animate 2024正式发布!

Adobe Animate 2024是一款全新的多平台动画和互动设计工具&#xff0c;它为用户提供了强大的工具和功能&#xff0c;以创造出各种类型的动画作品。无论是短片、广告、游戏还是交互式应用程序&#xff0c;Animate都能够满足您的需求。 Animate 2024的主要特点包括&#xff1a; …

mysql面试题48:MySQL中 Innodb的事务与日志的实现方式

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官: Innodb的事务与日志的实现方式 以下是InnoDB事务和日志的实现方式的详细说明: 事务日志(Transaction Log): InnoDB使用事务日志来保证事务的…

windows TBB的使用

windows TBB的使用 1. Install with GUI 1. Install with GUI To install oneTBB using GUI, complete the following steps: Go to the Download page.Select the preferred installer Online installer has a smaller file size but requires a permanent Internet connec…

计算机网络 | 网络层

计算机网络 | 网络层 计算机网络 | 网络层功能概述SDN&#xff08;Software-Defined Networking&#xff09;路由算法与路由协议IPv4IPv4 分组IPv4 分组的格式IPv4 数据报分片 参考视频&#xff1a;王道计算机考研 计算机网络 参考书&#xff1a;《2022年计算机网络考研复习指…

前端基础一:用Formdata对象来上传图片的原因

最近有人问&#xff1a;你是否能用json来传图片&#xff0c;其实应该这么理解就对了。 一、上传的数据体格式Content-Type 1.application/x-www-form-urlencoded 2.application/json 3.multipart/form-data 以上三种类型旨在告诉服务器需要接收的数据类型同事要…

企业级CI/CD 持续集成/交付/发布

jenkins 安装与使用 nmcli g hostname jenkins 加载缓存 yum makecache fast 上传jdk11、jdk8 获取、上传war包 1、jenkins.io/download 2.4.27 2、老师发的 上传 maven 上传tomcat软件包 &#xff08;apache.org-tomcat8-下载&#xff09; 注意8009端口 /usr... vi /etc/pro…

「蓝桥·算法双周赛」第一场公开赛

三带一【算法赛】 - 蓝桥云课 (lanqiao.cn) 给定四个字符&#xff0c;判断是否其中有三个相同&#xff0c;另一个与他们不同 #include <bits/stdc.h> void solve() {std::string s;std::cin>>s;char as[0],bs[1],cs[2],ds[3];if(ab&&ac&&a!d) std:…

Puppeteer监听网络请求、爬取网页图片(二)

Puppeteer监听网络请求、爬取网页图片&#xff08;二&#xff09; Puppeteer监听网络请求、爬取网页图片&#xff08;二&#xff09;一、爬取需求二、实现讲解三、效果查看 一、爬取需求 首先打开浏览器&#xff0c;打开指定网站监听网站发出的所有请求&#xff0c;记录请求&a…

【数据结构】线性表与顺序表

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 线性表与顺序表 1. 线性表2. 顺序表2.1 …

【Java 进阶篇】JavaScript 正则表达式(RegExp)详解

JavaScript 正则表达式&#xff0c;通常简写为 RegExp&#xff0c;是一种强大的文本匹配工具&#xff0c;它允许你通过一种灵活的语法来查找和替换字符串中的文本。正则表达式在编程中用途广泛&#xff0c;不仅限于 JavaScript&#xff0c;在许多编程语言中也都有类似的实现。 …

Spring MVC 十一:@EnableWebMvc

我们从两个角度研究EnableWebMvc&#xff1a; EnableWebMvc的使用EnableWebMvc的底层原理 EnableWebMvc的使用 EnableWebMvc需要和java配置类结合起来才能生效&#xff0c;其实Spring有好多Enablexxxx的注解&#xff0c;其生效方式都一样&#xff0c;通过和Configuration结合…