C#基于SkiaSharp实现印章管理(3)
本系列第一篇文章中创建的基本框架限定了印章形状为矩形,但常用的印章有方形、圆形等多种形状,本文调整程序以支持定义并显示矩形、圆角矩形、圆形、椭圆等4种形式的印章背景形状。
定义印章背景形状枚举类型,矩形、圆形、椭圆相关的尺寸能够根据印章宽度、高度计算,但圆角矩形需额外增加圆角半径尺寸,因此调整印章数据结构定义如下:
public enum BgType
{Rect=0,RoundRect=1,Circle=2,Oval=3
}public class SealInfo
{/// <summary>/// 印章名称/// </summary>public string Name { get; set; }=string.Empty;/// <summary>/// 印章宽度/// </summary>public float Width { get; set; } = 0;/// <summary>/// 印章高度/// </summary>public float Height { get; set; } = 0;/// <summary>/// 尺寸单位类型,默认为毫米/// </summary>public UnitType UnitType { get; set; } = UnitType.Mm;/// <summary>/// 印章背景色,默认白色/// </summary>public SKColor BgColor { get; set; }=SKColors.White;/// <summary>/// 背景形状类型/// </summary>public BgType BgType { get; set; } = BgType.Rect;/// <summary>/// 圆角半径/// </summary>public float CornerRadius { get; set; } = 0;/// <summary>/// 是否有边框/// </summary>public bool HasBorder { get; set; } = false;/// <summary>/// 边框宽度/// </summary>public float BorderWidth { get; set; } = 1;/// <summary>/// 边框颜色/// </summary>public SKColor BorderColor { get;set; } = SKColors.Red;
}
虽然SKPaint的Style 属性可以设置同时绘制边框和底色(值定义为StrokeAndFill),但还没有在帮助文档或其它文档中看到边框和底色不同颜色时的设置和绘制方式,因此只能采用比较笨的方式,先绘制底色再绘制边框,同一个绘制函数调用两次,两次之间修改绘制方式和绘制颜色。采用SKPath对象保存不同类型的印章形状,最终调用canvas.DrawPath函数统一绘制底色和边框,主要代码如下:
Func<float, int, float> unitConverter = m_currSeal.UnitType == UnitType.Pixel ? CommonFunction.Pixel2Pixel : CommonFunction.MM2Pixel; ;SKCanvas canvas = e.Surface.Canvas;canvas.Clear();SKPaint skPaint = new SKPaint();
skPaint.Style = SKPaintStyle.Fill;
skPaint.Color = m_currSeal.BgColor;float borderWidth = unitConverter(m_currSeal.BorderWidth, skBoard.DeviceDpi);
SKRect rect = new SKRect(borderWidth / 2, borderWidth / 2, unitConverter(m_currSeal.Width, skBoard.DeviceDpi) - borderWidth / 2, unitConverter(m_currSeal.Height, skBoard.DeviceDpi) - borderWidth / 2);SKPath path = new SKPath();switch (m_currSeal.BgType)
{case BgType.Rect:path.AddRect(rect);break;case BgType.RoundRect:path.AddRoundRect(new SKRoundRect(rect, unitConverter(m_currSeal.CornerRadius, skBoard.DeviceDpi)));break;case BgType.Circle:path.AddCircle(rect.MidX, rect.MidY, Math.Min(rect.Height / 2, rect.Width / 2));break;case BgType.Oval:path.AddOval(rect);break;
}canvas.DrawPath(path, skPaint);if(m_currSeal.HasBorder)
{skPaint.StrokeWidth = borderWidth;skPaint.Style = SKPaintStyle.Stroke;skPaint.Color = m_currSeal.BorderColor;canvas.DrawPath(path, skPaint);
}
最后是程序运行效果,如下图所示:

参考文献:
[1]https://learn.microsoft.com/zh-cn/dotnet/api/skiasharp?view=skiasharp-2.88
相关文章:
C#基于SkiaSharp实现印章管理(3)
本系列第一篇文章中创建的基本框架限定了印章形状为矩形,但常用的印章有方形、圆形等多种形状,本文调整程序以支持定义并显示矩形、圆角矩形、圆形、椭圆等4种形式的印章背景形状。 定义印章背景形状枚举类型,矩形、圆形、椭圆相关的尺寸…...
如何理解泛型的编译期检查
既然说类型变量会在编译的时候擦除掉,那为什么我们往 ArrayList 创建的对象中添加整数会报错呢?不是说泛型变量String会在编译的时候变为Object类型吗?为什么不能存别的类型呢?既然类型擦除了,如何保证我们只能使用泛型…...
计算机组成原理:海明校验
在上图中,对绿色的7比特数据进行海明校验,需要添加紫色的4比特校验位,总共是蓝色的11比特。紫色的校验位pi分布于蓝色的hi的1, 2, 4, 8, 16, 32, 64位,是2i-1位。绿色的数据位bi分布于剩下的位。 在下图中,b1位于h3&a…...
信息学奥赛初赛天天练-39-CSP-J2021基础题-哈夫曼树、哈夫曼编码、贪心算法、满二叉树、完全二叉树、前中后缀表达式转换
PDF文档公众号回复关键字:20240629 2022 CSP-J 选择题 单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项) 5.对于入栈顺序为a,b,c,d,e的序列,下列( )不合法的出栈序列 A. a,b&a…...
第11章 规划过程组(收集需求)
第11章 规划过程组(一)11.3收集需求,在第三版教材第377~378页; 文字图片音频方式 第一个知识点:主要输出 1、需求跟踪矩阵 内容 业务需要、机会、目的和目标 项目目标 项目范围和 WBS 可…...
探索WebKit的守护神:深入Web安全策略
探索WebKit的守护神:深入Web安全策略 在数字化时代,网络已成为我们生活的一部分,而网页浏览器作为我们探索网络世界的窗口,其安全性至关重要。WebKit作为众多流行浏览器的内核,例如Safari,其安全性策略是保…...
unity ScrollRect裁剪ParticleSystem粒子
搜了下大概有这几种方法 通过模板缓存通过shader裁剪区域:案例一,案例二,案例三,三个案例都是类似的方法,需要在c#传入数据到shader通过插件 某乎上的模板缓存方法link,(没有登录看不到全文&a…...
凤仪亭 | 第7集 | 大丈夫生居天地之间,岂能郁郁久居人下 | 司徒一言,令我拨云见日,茅塞顿开 | 三国演义 | 逐鹿群雄
🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 📌这篇博客分享的是《三国演义》文学剧本第Ⅰ部分《群雄逐鹿》的第7️⃣集《凤仪亭》的经典语句和文学剧本全集台词 文章目录 1.经典语句2.文学剧本台词 …...
React实战学习(一)_棋盘设计
需求: 左上侧:状态左下侧:棋盘,保证胜利就结束 和 下过来的不能在下右侧:“时光机”,保证可以回顾,索引 语法: 父子之间属性传递(props)子父组件传递(写法上&…...
【LeetCode】每日一题:三数之和
解题思路 最开始是打算沿着二数之和的思路做,即固定了最大的,然后小的开始遍历,因为这种遍历方式只需要遍历一轮就能完成,所以复杂度应该是O(n2),但是最后几个示例还是超时了,可能进…...
逆风而行:提升逆商,让困难成为你前进的动力
一、引言 生活,总是充满了未知与变数。有时,我们会遇到阳光明媚的日子,享受着宁静与和谐;但更多时候,我们却不得不面对那些突如其来的坏事件,如工作的挫折、人际关系的困扰、健康的挑战等。这些事件如同突…...
新能源汽车CAN总线故障定位与干扰排除的几个方法
CAN总线是目前最受欢迎的现场总线之一,在新能源车中有广泛应用。新能源车的CAN总线故障和隐患将影响驾驶体验甚至行车安全,如何进行CAN总线故障定位及干扰排除呢? 目前,国内机动车保有量已经突破三亿大关。由于大量的燃油车带来严峻的环境问题,因此全面禁售燃油车的日程在…...
【涵子来信】——社交宝典:克服你心中的内向,世界总有缺陷
内向,你是内向的吗?想必每个人不同,面对的情形也是不同的。 暑假是一个很好的机会,我是可以去多社交社交。但是,面对着CSDN上这么多技术人er,那么,我的宝典,对于大家,有…...
LabVIEW项目外协时选择公司与个人兼职的比较
在选择LabVIEW项目外协合作伙伴时,外协公司和个人兼职各有优劣。个人兼职成本较低且灵活,但在可靠性、技术覆盖面、资源和风险管理上存在不足。而外协公司拥有专业团队、丰富资源、完善的项目管理和风险控制,尽管成本较高,但能提…...
汽车电子工程师入门系列——CAN 规范系列通读
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...
泽众云真机-平台华为机型HarmonyOS NEXT系统已上线!
泽众云真机平台华为机型HarmonyOS NEXT系统已上线! 之前文章《泽众云真机-平台即将升级支持华为机型HarmonyOS NEXT系统泽众云真机-平台即将升级支持华为机型HarmonyOS NEXT系统》,为什么要升级HarmonyOS NEXT系统?我们之前有说过,…...
AI基础:从线性回归到梯度下降
一个简单的问题: 如果此时你正站在迷路缭绕的山坡上,能见度不高,但是你又想去往最低的山谷的位置,怎么走? 很简单,哪里陡那就往那里走呗——而这就是梯度下降算法的思想。 古话说:“先发制于人…...
AI产品经理面试
把优秀当习惯把优秀当习惯肯定不是口头说说,那有什么判断标准吗? 当我做完一件事儿的时候,我会看它有没有突破我的舒适圈、能不能惊艳到我自己。这就是我的判断标准。 在自我介绍和经历介绍时,面试者应该注重以下几个方面…...
二进制方式部署consul单机版
1.consul的下载 mkdir -p /root/consul/data && cd /root/consul wget https://releases.hashicorp.com/consul/1.18.0/consul_1.18.0_linux_amd64.zip unzip consul_1.18.0_linux_amd64.zip mv consul /usr/local/bin/ 2.配置文件 // 配置文件路径: /roo…...
SpringBoot整合Quartz实现动态定时任务
目录 1、Quartz简介1.1 Quartz的三大核心组件1.2 CronTrigger配置格式 2、SpringBoot整合Quartz框架2.1 创建项目2.2 实现定时任务 1、Quartz简介 Quartz是一个开源的任务调度服务,它可以独立使用,也可与其它的Java EE,Java SE应用整合使用。…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
