C#基于SkiaSharp实现印章管理(1)

  最近对着微软的教程学习SkiaSharp的概念及用法,由于之前使用GDI+绘制过坐标系、印章等程序,准备使用SkiaSharp、SKControl控件编写简单的印章设计功能,并能用印章对图片盖章。本文实现创建印章背景、序列化及反序列化印章对象等功能。
  VS2022新建Winform项目,在Nuget包管理器中搜索并安装以下包:

SkiaSharp
SkiaSharp.Views
SkiaSharp.Views.Forms
SkiaSharp.Views.Forms.WPF

  印章一般是白底红边框,或者没有边框,本文暂不考虑印章内部的文字、线条、圆/椭圆等样式,定义以下类型保存印章的背景色、尺寸、边框颜色、边框宽度等信息。

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 bool HasBorder { get; set; } = false;/// <summary>/// 边框宽度/// </summary>public float BorderWidth { get; set; } = 1;/// <summary>/// 边框颜色/// </summary>public SKColor BorderColor { get;set; } = SKColors.Red;
}

  支持两种尺寸单位类型:毫米、像素。一般都是按毫米设置印章尺寸,因此绘制印章时需要从毫米转换到像素(SkiaSharp尺寸单位默认为像素,暂时没有看到设置其它计量单位的方式)。像素和毫米转换时需要用到控件的DPI,GDI+的Graphics对象中支持获取DpiX和DpiY,但是SKCanvas中没有DPI数据,而是保存在SKControl的DeviceDpi属性,且仅有单个属性,并未区分X和Y方向。
  同时关于SKColor和System.Drawing.Color之间的转换,SkiaSharp.Views.Desktop.Common程序集的扩展类中提供了扩展函数ToDrawingColor,支持将SKColor转换为System.Drawing.Color,而程序集System.Drawing.Primitives的ColorTranslator类的函数ToHtml支持将System.Drawing.Color转换为十六进制字符串,然后调用SKColor.Parse转换为SKColor实例,以下示例代码调用Winform的颜色选择组件设置背景颜色:

ColorDialog colorDialog = new ColorDialog();
colorDialog.Color = m_seal.BgColor.ToDrawingColor();
if (colorDialog.ShowDialog() == DialogResult.OK)
{//m_seal.BgColor = SKColor.Parse(String.Format("#{0:X2}{1:X2}{2:X2}", colorDialog.Color.R, colorDialog.Color.G, colorDialog.Color.B));m_seal.BgColor = SKColor.Parse(System.Drawing.ColorTranslator.ToHtml(colorDialog.Color));txtBgColor.Text = m_seal.BgColor.ToString();
}

  调用System.Text.Json.JsonSerializer序列化及反序列化SealInfo对象实例,下图是序列化结果,但是反序列化时SKColor对象的值没有正确获取,还不清楚问题原因。
在这里插入图片描述
  最后是主要绘图代码及程序运行效果:

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;canvas.DrawRect(0, 0, unitConverter(m_currSeal.Width, skBoard.DeviceDpi), unitConverter(m_currSeal.Height, skBoard.DeviceDpi), sKPaint);if(m_currSeal.HasBorder)
{sKPaint.Style = SKPaintStyle.Stroke;sKPaint.Color = m_currSeal.BorderColor;float borderWidth= unitConverter(m_currSeal.BorderWidth, skBoard.DeviceDpi);sKPaint.StrokeWidth= borderWidth;SKRect rect = new SKRect(borderWidth / 2, borderWidth / 2, unitConverter(m_currSeal.Width, skBoard.DeviceDpi) - borderWidth / 2, unitConverter(m_currSeal.Height, skBoard.DeviceDpi) - borderWidth / 2); canvas.DrawRect(rect, sKPaint);
}

在这里插入图片描述

在这里插入图片描述

参考文献:
[1]https://learn.microsoft.com/zh-cn/previous-versions/xamarin/xamarin-forms/user-interface/graphics/skiasharp/

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

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

相关文章

PostgreSQL进阶教程

PostgreSQL进阶教程 目录 事务和并发控制 事务事务隔离级别锁 高级查询 联合查询窗口函数子查询CTE&#xff08;公用表表达式&#xff09; 数据类型 自定义数据类型数组JSON 高级索引 部分索引表达式索引GIN和GiST索引 性能调优 查询优化配置优化 备份与恢复 物理备份逻辑备份…

2-14 基于matlab的GA优化算法优化车间调度问题

基于matlab的GA优化算法优化车间调度问题。n个工作在m个台机器上加工。已知每个工作中工序加工顺序、各工序的加工时间以及每个工件所包含的工序&#xff0c;在满足约束条件的前提下&#xff0c;目的是确定机器上各工件顺序&#xff0c;以保证某项性能指标最优。程序功能说明&a…

视频讲解|【双层模型】分布式光伏储能系统的优化配置方法

1 主要内容 该讲解视频对应的程序链接为【双层模型】分布式光伏储能系统的优化配置方法&#xff0c;模型参考《分布式光伏储能系统的优化配置方法》&#xff0c;分为上下层求解方式&#xff0c;上层采用粒子群算法确定储能的选址和容量方案&#xff0c;以全年购电成本、网络损…

YouTube API接口:一键获取Playlist视频合集信息

核心功能介绍 在视频内容日益繁荣的今天&#xff0c;YouTube作为全球领先的视频分享平台&#xff0c;为内容创作者、品牌商家以及数据分析师提供了丰富的视频资源。其中&#xff0c;Playlist视频合集作为YouTube上的一种特色内容形式&#xff0c;深受用户喜爱。为了更好地满足…

TCP与UDP_三次握手_四次挥手

TCP vs UDP TCP数据 具体可以通过Cisco Packet Tracer工具查看&#xff1a; UDP数据 三次握手、四次挥手 为什么是3/4次&#xff1f;这牵扯到单工、双工通信的问题 TCP建立连接&#xff1a;表白 TCP释放连接&#xff1a;分手 TCP—建立连接—三次握手 解释&#xff1a; 首先&…

HTML与CSS的初步解析及实践案例

目录 1&#xff0c;HTML概览与基本语法 基本结构&#xff1a; 头部标签&#xff1a; 常用标签与属性 CSS概述与基本语法 CSS选择器与属性 盒子模型与布局 实例展示 1&#xff0c;HTML概览与基本语法 HTML&#xff0c;即超文本标记语言&#xff0c;是网页的基础构建语言…

本地离线模型搭建指南-LLaMA-Factory训练框架及工具

搭建一个本地中文大语言模型&#xff08;LLM&#xff09;涉及多个关键步骤&#xff0c;从选择模型底座&#xff0c;到运行机器和框架&#xff0c;再到具体的架构实现和训练方式。以下是一个详细的指南&#xff0c;帮助你从零开始构建和运行一个中文大语言模型。 本地离线模型搭…

【面试】基本数据类型的包装类缓存

目录 1. 说明2. Integer类分析2.1 代码块2.2 字节码2.3 分析2.4 valueOf方法 1. 说明 1.在java中&#xff0c;基本数据类型的包装类&#xff08;Integer、Byte、Character、Short、Long、Boolean&#xff09;的某些值会被缓存。2.以提高性能并减少内存使用。3.这种缓存机制是自…

Rxjava2最全面的解析

说到区别&#xff0c;可能有的小伙伴会问&#xff0c;我没看过rxjava1。可以直接看rxjava2么。个人觉得不必要&#xff0c;因为 rxjava2.x 是按照 Reactive-Streams specification 规范完全的重写的&#xff0c;完全独立于 rxjava1.x 而存在&#xff0c;它改变了以往 rxjava1的…

如何看待鸿蒙HarmonyOS?

鸿蒙系统&#xff0c;自2019年8月9日诞生就一直处于舆论风口浪尖上的系统&#xff0c;从最开始的“套壳”OpenHarmony安卓的说法&#xff0c;到去年的不再兼容安卓的NEXT版本的技术预览版发布&#xff0c;对于鸿蒙到底是什么&#xff0c;以及鸿蒙的应用开发的讨论从来没停止过。…

物联网系统运维——移动电商服务器单点部署,web服务器部署,Nginx Web服务介绍,Nginx性能,部署,架构,及实验:安装并设置Nginx(重点)

一.web服务器介绍 Web服务器一般指网站服务器&#xff0c;是指驻留于因特网上提供某种特定类型计算机的程序&#xff0c;Web服务器可以向浏览器等Web客户端提供文档&#xff0c;也可以放置网站文件&#xff0c;让全世界浏览&#xff0c;可以放置数据文件&#xff0c;让全世界下…

力扣SQL50 游戏玩法分析 IV 子查询

Problem: 550. 游戏玩法分析 IV &#x1f468;‍&#x1f3eb; 参考题解 这个SQL查询的目的是计算每个玩家在登录后的第二天参与活动的比例。查询使用了子查询和左连接来实现这一目的。下面是查询的详细解释&#xff0c;包括每个部分的作用和注释&#xff1a; -- 计算每个玩…

Leetcode 3192. Minimum Operations to Make Binary Array Elements Equal to One II

Leetcode 3192. Minimum Operations to Make Binary Array Elements Equal to One II 1. 解题思路2. 代码实现 题目链接&#xff1a;3192. Minimum Operations to Make Binary Array Elements Equal to One II 1. 解题思路 这一题的话就是一个动态规划&#xff0c;我们使用两…

【K8S运维】整理常见使用命令

*特别提醒: 文件复制类的命令&#xff0c;执行命令等需要谨慎确定命令执行后的效果&#xff0c;否则一旦出错就不可逆&#xff01;&#xff01;&#xff01; 命令概览 序号使用场景命令格式使用样例命令使用说明1查询集群节点有多少kubectl get nodes2查询集群运行哪些podkub…

文华财经多空精准买卖点止损止盈数值主图指标公式源码

文华财经多空精准买卖点止损止盈数值主图指标公式源码&#xff1a; DD:EVERY(H>HV(H,20),1); KK:EVERY(L<LV(L,20),1); D:DD&&SUM(DD,BARSLAST(KK))1; K:KK&&SUM(KK,BARSLAST(DD))1; Y:1; DRAWCOLORKLINE(Y&&ISDOWN,COLORYELLOW,0); DRAW…

【原创】springboot+mysql海鲜商城设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

Vue的Router?一个小demo秒了

效果展示 正文 登录页 <template><div><div class"login"><h3>图书管理系统</h3><div class"user"><span>账号&#xff1a;</span><input type"text" v-model"user" /></…

193.回溯算法:组合总和(力扣)

代码解决 class Solution { public:vector<int> res; // 当前组合的临时存储vector<vector<int>> result; // 存储所有符合条件的组合// 回溯函数void backtrcing(vector<int>& nums, int target, int flag, int index) {// 如果当前组合的和超过了…

C++:字符串string类使用

C字符串和C字符串的对比 (1)C语言严格说没有字符串的概念&#xff0c;C字符串其实就是字符数组或字符指针 (2)C和之后的java等都有字符串&#xff0c;本质是一个class (3)C字符串的优势是标准库自带可用于字符串的各种处理算法和方法 (4)C实际开发中建议使用C字符串而不是沿用…

高可用电商支付架构设计方案

高可用电商支付架构设计 在现代电商业务中&#xff0c;支付过程是其中至关重要的一环&#xff0c;一个高可用、安全稳定的支付架构不仅可以提高整个系统的可靠性和扩展性&#xff0c;降低维护成本&#xff0c;还可以优化用户体验&#xff0c;增加用户黏性。 本文将提出一种高…