当前位置: 首页 > news >正文

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/

相关文章:

  • oracle12c dataguard搭建及切换
  • React组件卸载的几种情况
  • Nikto一键扫描Web服务器(KALI工具系列三十)
  • 【break】大头哥哥做题
  • vue登陆密码加密,java后端解密
  • Jenkins+K8s实现持续集成(二)
  • [数据集][目标检测]药片药丸检测数据集VOC+YOLO格式152张1类别
  • 理解堆排序
  • Golang中的CAS操作
  • 算法训练营第六十七天 | 卡码网110 字符串接龙、卡码网105 有向图的完全可达性、卡码网106 岛屿的周长
  • 【操作系统】第五章 文件系统
  • odoo的采购询价单,默认情况下显示‘draft‘,‘sent‘,‘purchase‘,请问什么情况下才会显示‘to approve‘?
  • clean code-代码整洁之道 阅读笔记(第十一章)
  • 静态ip详解
  • Android面试题精选——再聊Android-Handler机制
  • @jsonView过滤属性
  • [ JavaScript ] 数据结构与算法 —— 链表
  • CODING 缺陷管理功能正式开始公测
  • LeetCode算法系列_0891_子序列宽度之和
  • PAT A1092
  • vuex 学习笔记 01
  • 从PHP迁移至Golang - 基础篇
  • 工作手记之html2canvas使用概述
  • 简单易用的leetcode开发测试工具(npm)
  • 将 Measurements 和 Units 应用到物理学
  • 你不可错过的前端面试题(一)
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 使用SAX解析XML
  • 世界上最简单的无等待算法(getAndIncrement)
  • 微信开放平台全网发布【失败】的几点排查方法
  • 我有几个粽子,和一个故事
  • MyCAT水平分库
  • 阿里云重庆大学大数据训练营落地分享
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • # include “ “ 和 # include < >两者的区别
  • #include到底该写在哪
  • (1)(1.11) SiK Radio v2(一)
  • (C语言)球球大作战
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (笔试题)分解质因式
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (力扣)1314.矩阵区域和
  • (十五)使用Nexus创建Maven私服
  • (十一)图像的罗伯特梯度锐化
  • (四)汇编语言——简单程序
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)用.Net的File控件上传文件的解决方案
  • .libPaths()设置包加载目录
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福