问题描述

看见一个有趣的页面,可以把输入的文字信息,直接输出SVG图片,还可以实现动图模式。

示例URL: 

https://readme-typing-svg.demolab.com/?font=Fira+Code&pause=1000&color=F7F7F7&background=233911F6&center=true&vCenter=true&random=false&width=435&lines=%E6%8A%8A%E5%AD%97%E5%8F%98%E5%8A%A8%E5%8A%A8%E5%9B%BE%E8%BE%93%E5%87%BA

示例效果:

那么,用.NET API怎么来快速实现这个目的呢?

问题解答

通过查看示例URL的Response Headers 和 Body Content,发现其使用的 Content-Type  image/svg+xml , 内容使用svg, pathanimate, text元素组合而成的HTML代码。

Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件

SVG 意为可缩放矢量图形(Scalable Vector Graphics)。 SVG 使用 XML 格式定义图像。

SVG 路径 - <path> 元素用于定义一个路径。 <path d="M150 0 L75 200 L225 200 Z" /> 它开始于位置150 0,到达位置75 200,然后从那里开始到225 200,最后在150 0关闭路径。

<animate>  随时间动态改变属性

所以是不是只要API的返回体相类似就可以呢?

试验开始

第一步:在Visual Studio 2022中,创建一个.NET Core WEBAPI项目,使用top-level statements.

第二步:设置app.MapGet("/",  ...),添加 httpResponse 参数并在函数体中设置 httpResponse.ContentType = "image/svg+xml"

第三步:直接把示例URL中的全部返回作为 httpResponse  内容输出,F5运行项目测试效果。

app.MapGet("/", async (HttpResponse httpResponse) =>
{
httpResponse.ContentType = "image/svg+xml";
string content = "<!-- https://github.com/DenverCoder1/readme-typing-svg/ -->\r\n<svg xmlns='http://www.w3.org/2000/svg'\r\n xmlns:xlink='http://www.w3.org/1999/xlink'\r\n viewBox='0 0 435 50'\r\n style='background-color: #233911F6;'\r\n width='435px' height='50px'>\r\n <path id='path0'>\r\n <!-- Single line -->\r\n <animate id='d0' attributeName='d' begin='0s;d0.end'\r\n dur='6000ms' fill='remove'\r\n values='m0,25 h0 ; m0,25 h435 ; m0,25 h435 ; m0,25 h0' keyTimes='0;0.66666666666667;0.83333333333333;1' />\r\n </path>\r\n <text font-family='\"Fira Code\", monospace' fill='#F7F7F7' font-size='20'\r\n dominant-baseline='middle'\r\n x='50%' text-anchor='middle'>\r\n <textPath xlink:href='#path0'>\r\n 把字变动动图输出\r\n </textPath>\r\n </text>\r\n</svg>\r\n";
await httpResponse.WriteAsync(content);
await httpResponse.Body.FlushAsync();
});

测试成功,达到预期的效果。

第四步:优化代码,把文本和颜色变为参数

获取 Request中携带的参数 name 和 hex来替换HTML中的文本与颜色值。

PS: 如果有更多的需求,如多行字体,字体,大小,SVG的长宽等,都可以把提取出来变为参数。

完整代码如下:

app.MapGet("/tosvg", async (HttpRequest request, HttpResponse httpResponse) =>
{
string name = request.Query["name"];
string colorHex = request.Query["hex"]; name = name ?? "No Name";
colorHex = colorHex ?? "3943BB";
httpResponse.ContentType = "image/svg+xml"; if (name.Contains("("))
{
name = name.Substring(0, name.IndexOf('('));
} await httpResponse.WriteAsync(GenerateSVGcontent(name, colorHex));
await httpResponse.Body.FlushAsync(); }); string GenerateSVGcontent(string name, string colorHex = "#3943BB")
{
StringBuilder sb = new StringBuilder(); sb.Append("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 200 100' style='background-color:" + colorHex + ";' width='200px' height='100px'>");
sb.Append("<path id='path0'><animate id='d0' attributeName='d' begin='0s' dur='3000ms' fill='freeze' values='m0,50 h0 ; m0,50 h200 ; m0,50 h200 ; m0,50 h200' keyTimes='0;0.72727272727273;0.81818181818182;1' /></path>");
sb.Append("<text font-family='\"Arial\", monospace' fill='#FFFFFF' font-size='20' dominant-baseline='middle' x='50%' text-anchor='middle'>");
sb.Append("<textPath xlink:href='#path0'>");
sb.Append(name);
sb.Append("</textPath></text>\r\n</svg>"); return sb.ToString();
}

第五步:在VS2022中,一键部署到Azure App Service,轻松提供一个HTTP/S API实现文字转动图功能。

附录:完整的示例代码

using System.Text;
var builder = WebApplication.CreateBuilder(args); // Add services to the container.
var app = builder.Build();
app.MapGet("/", async (HttpResponse httpResponse) =>
{
httpResponse.ContentType = "image/svg+xml";
string content = "<!-- https://github.com/DenverCoder1/readme-typing-svg/ -->\r\n<svg xmlns='http://www.w3.org/2000/svg'\r\n xmlns:xlink='http://www.w3.org/1999/xlink'\r\n viewBox='0 0 435 50'\r\n style='background-color: #233911F6;'\r\n width='435px' height='50px'>\r\n <path id='path0'>\r\n <!-- Single line -->\r\n <animate id='d0' attributeName='d' begin='0s;d0.end'\r\n dur='6000ms' fill='remove'\r\n values='m0,25 h0 ; m0,25 h435 ; m0,25 h435 ; m0,25 h0' keyTimes='0;0.66666666666667;0.83333333333333;1' />\r\n </path>\r\n <text font-family='\"Fira Code\", monospace' fill='#F7F7F7' font-size='20'\r\n dominant-baseline='middle'\r\n x='50%' text-anchor='middle'>\r\n <textPath xlink:href='#path0'>\r\n 把字变动动图输出\r\n </textPath>\r\n </text>\r\n</svg>\r\n";
await httpResponse.WriteAsync(content);
await httpResponse.Body.FlushAsync();
}); app.MapGet("/tosvg", async (HttpRequest request, HttpResponse httpResponse) =>
{
string name = request.Query["name"];
string colorHex = request.Query["hex"];
//name = name:? "Name";
name = name ?? "No Name";
colorHex = colorHex ?? "3943BB";
httpResponse.ContentType = "image/svg+xml"; if (name.Contains("("))
{
name = name.Substring(0, name.IndexOf('('));
}
await httpResponse.WriteAsync(GenerateSVGcontent(name, colorHex));
await httpResponse.Body.FlushAsync(); }); string GenerateSVGcontent(string name, string colorHex = "#3943BB")
{
StringBuilder sb = new StringBuilder(); sb.Append("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 200 100' style='background-color:" + colorHex + ";' width='200px' height='100px'>"); sb.Append("<path id='path0'><animate id='d0' attributeName='d' begin='0s' dur='3000ms' fill='freeze' values='m0,50 h0 ; m0,50 h200 ; m0,50 h200 ; m0,50 h200' keyTimes='0;0.72727272727273;0.81818181818182;1' /></path>");
//sb.Append("<path id='path0'><animate id='d0' attributeName='d' begin='0s;d0.end' dur='2200ms' fill='remove' values='m0,50 h0 ; m0,50 h200 ; m0,50 h200 ; m0,50 h0' keyTimes='0;0.72727272727273;0.81818181818182;1' /> </path>");
sb.Append("<text font-family='\"Arial\", monospace' fill='#FFFFFF' font-size='20' dominant-baseline='middle' x='50%' text-anchor='middle'>");
sb.Append("<textPath xlink:href='#path0'>");
sb.Append(name);
sb.Append("</textPath></text>\r\n</svg>"); return sb.ToString();
} app.Run();

参考资料

Readme Typing SVG : https://readme-typing-svg.demolab.com/demo/

HTTP content-type : https://www.runoob.com/http/http-content-type.html

<animate> : https://www.runoob.com/svg/svg-reference.html

【Azure Developer】.Net 简单示例 "文字动图显示" Typing to SVG的更多相关文章

  1. 报告撰写,linux使用gimp简单做gif动图

    我想把我的系统菜单完整记录下来,方便查看,如果单纯使用文字比较单调,使用屏幕截图,需要依次打开多个图像查看也不是很方便,就想到了使用动画的形式展示.由于本人的系统一直使用Linux系统,为了一张gif ...

  2. css如何简单设置文字溢出盒子显示省略号

    1.单行文本溢出显示省略号单行文本溢出显示省略号,必须满足三个条件:(1)先强制一行内显示文本white-space:nowrap;(默认 normal自动换行)(2)超出的部分隐藏overflow: ...

  3. matplotlib简单示例

    一.简介 以下引用自百度百科 Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形 . 通过 Matplotlib,开发者可以仅需要 ...

  4. 怎样录制简单GIF动图

    看到视频里的精彩画面,想用动图的形式保存下来,应该如何录制呢,今天就介绍一款小巧实用,操作简单的软件,GifCam 2.0 汉化绿色版.相比其它的录制软件,它是免费无水印又可以在线录制的. 本来学习一 ...

  5. 【Azure Developer】解决Azure Key Vault管理Storage的示例代码在中国区Azure遇见的各种认证/授权问题 - C# Example Code

    问题描述 使用Azure密钥保管库(Key Vault)来托管存储账号(Storage Account)密钥的示例中,从Github中下载的示例代码在中国区Azure运行时候会遇见各种认证和授权问题, ...

  6. 用STM32玩OLED(显示文字、图片、动图gif等)

    目录 用STM32玩OLED(显示文字.图片.动图gif等) 1. 显示字符串 2. 显示中文 3. 显示图片 4. 显示动图 5. 总结测试 用STM32玩OLED(显示文字.图片.动图gif等) ...

  7. 实用的Python(2)利用Python制作gif动图

    一.简介 moviepy是一个专门用于视频剪辑制作的模块,可以自动化完成很多繁琐的视频剪辑处理工作,除了处理视频数据之外,moviepy中还内置了可以制作gif动图的功能,通过使用moviepy.ed ...

  8. 【动图解释】关系数据库de关系代数小记

    本文章在 Github 撰写,同时在 我的博客 进行了发布. 最近学数据库概论学到了关系数据库的关系代数了.哎嘛,真的把我整晕了,尤其是关系代数的使用,很容易让人被蒙在鼓里. 对我来说槽点最大的莫过于 ...

  9. Vue过渡和动画效果展示(案例、GIF动图演示、附源码)

    前言 本篇随笔主要写了Vue过渡和动画基础.多个元素过渡和多个组件过渡,以及列表过渡的动画效果展示.详细案例分析.GIF动图演示.附源码地址获取. 作为自己对Vue过渡和动画效果知识的总结与笔记. 因 ...

  10. 分享超好用的截动图工具ScreenToGif

    安装很简单,首先看看本地是否安装了.Net Framework 4.6.1,没有就在微软官网搜一下,选[离线安装包]版本 下载安装后,直接安装ScreenToGif即可使用(有绿色版,免安装) htt ...

随机推荐

  1. 4、dubbo的高可用

    1.zookeeper宕机与dubbo直连 现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务. 原因: 健壮性 l 监控中心宕掉不影响使用,只是丢失部分采样数据 l 数据库宕掉后, ...

  2. MVC阶段所有框架完整组合示例

    思路:创建工程,导包.编辑配置文件包括 核心spring配置   SpringConfig myBatis 配置文件  mybatisConfig  JdbcConfig  jdbc.properti ...

  3. 摆脱鼠标系列 vscode 向右拆分编辑器 ctrl + 右箭头

    摆脱鼠标系列 vscode 向右拆分编辑器 ctrl + 右箭头 为什么 今天看见一个两栏工作的,左侧放的是目录大纲,右侧是代码内容 用快捷键 ctrl + 右箭头 快速扩展一个,关闭可以ctrl + ...

  4. vuecli-vite-vue3-init 项目架子 快速开发 webpack打包

    要vite的开发的快速 和 webpack打包 开发的时候 用vite,可以打包一个本地可以直接双击,不用起服务的代码 这个架子的缺点就是 vite和vuecli 两套双配置 正式公司项目 还是vue ...

  5. PE文件手工压缩

    序 本文要压缩的PE文件来自软件漏洞这门课上布置的作业,代码逻辑很简单,直接运行就能看出来,就是调库来弹两个对话窗口.笔者主要记录一下对这个文件的分析和一步步实现手工压缩的过程.在此提供原文件的下载方 ...

  6. 基于 XAF Blazor 的规则引擎编辑器 - 实战篇

    示例项目:https://gitee.com/easyxaf/recharge-rules-engine-sample 前言 继上一篇文章对规则引擎编辑器进行了初步介绍之后,本文将通过实际应用案例深入 ...

  7. python高级技术(进程一)

    一 什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实 ...

  8. 三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析

    三维模型3DTile格式轻量化压缩处理效率提高的技术方浅析 随着三维模型在各个领域的广泛应用,对于其格式的轻量化压缩处理和效率提高的需求也越发迫切.本文将介绍一些技术方法,帮助实现三维模型3DTile ...

  9. 你是怎么理解ES6中 Generator的?使用场景?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.介绍 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同 回顾下上文提到的解决异步的手段: 回 ...

  10. 提升团队协作效率:欧奥PicHome打造无缝资料共享平台

    1. 引言 在快节奏的工作环境中,团队成员需要快速访问和共享信息.有效的资料共享不仅提高工作效率,还能促进团队协作和创新.然而,许多团队仍在使用传统的文件共享方法,这些方法往往效率低下,难以满足现代工 ...