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

news/2024/9/30 0:11:11 标签: c#, PdfSharpCore

  向PDF文件插入印章图片比之前实现的向图片文件插入印章麻烦得多。
  最初的想法是使用PDF浏览控件在线打开PDF文件,然后在控件中实现鼠标移动时动态显示印章,点击鼠标时向当前PDF页面的鼠标点击位置插入图片。由于是.net 8的Winform项目,选用PdfiumViewer模块的浏览控件打开并显示PDF文档,但是测试时发现无法触发控件的paint事件,也就难以实现印章图片随鼠标移动,同时虽然PdfiumViewer的扩展包Pdfium.Net.Free支持向PDF页面插入图片(参考文献4),但是同时安装PdfiumViewer、pdfium依赖包、Pdfium.Net.Free时打开PDF文件会报错,提示pdfium.dll文件版本出错,网上有解决办法,但比较麻烦,最终决定不用PDF浏览控件。
  采用图片方式显示单页PDF文档,通过指定页码跳转到指定页面。采用iText7模块打开PDf文档、获取页码数量,同时安装ThomSoft.itext7.pdfimage包,支持将pdf文档的页面转换为图片,这样就类似于向图片盖印章的模式。iText7支持使用PdfCanvas向页面中绘制文本、形状、图片等,但是实际测试过程中使用PdfCanvas向已有内容的页面中绘制图片时遇到各种报错,最终也没有成功,百度出来的示例代码都是新建页面,然后向页面中从零开始绘制文本、形状、图片等元素,没有找到需要的代码。
  itextsharp模块可以向pdf文件中插入图片,但是itextsharp模块用于.net framework项目,无法用于.net 8项目。
  最终选用PdfSharpCore模块向PDF页面插入图片,使用比较简单,主要代码如下所示:

PdfSharpCore.Pdf.PdfDocument doc =PdfSharpCore.Pdf.IO.PdfReader.Open(pnlPdf.Tag.ToString(), PdfDocumentOpenMode.Modify);
XImage background = XImage.FromFile(comboSeal.Text);
PdfSharpCore.Pdf.PdfPage page = doc.Pages[Convert.ToInt32(nudPage.Value)-1];
XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsUnit.Point);

XRect rect = new XRect(page.Width*(e.X - m_startX) / (m_scale*m_srcImageBmp.Width),
                       page.Height * (e.Y - m_startY) / (m_scale * m_srcImageBmp.Height),
                       page.Width*background.PixelWidth/m_srcImageBmp.Width,
                       page.Height * background.PixelHeight / m_srcImageBmp.Height);

//写入指定位置
gfx.DrawImage(background, rect);
doc.Save("test2022.pdf");

  测试过程中遇到的问题是PdfSharpCore模块将PDF页面导出图片很麻烦,因此还是采用iText7及ThomSoft.itext7.pdfimage包打开PDF文件并将指定页面转换为图片后在窗口中显示。鼠标点击控件盖章时计算鼠标在当前页面位置,然后用PdfSharpCore模块打开PDF文档、获取当前页面对象,绘制印章图片。但是itext7生成的图片尺寸和PdfSharpCore模块的页面尺寸不一致,导致根据鼠标点击位置计算印章图片的插入位置及尺寸时始终不对,最后没有太好的办法,只能计算印章图片与窗口图片的相对位置及尺寸,再根据PdfSharpCore模块打开的页面尺寸计算在页面中的位置及尺寸,结果勉强能用,但算不上所见即所得。后续还得继续调整程序。
  下面是窗口截图及导出的pdf文档中插入图片的效果。
在这里插入图片描述
在这里插入图片描述

参考文献:
[1]https://learn.microsoft.com/zh-cn/dotnet/api/skiasharp?view=skiasharp-2.88
[2]https://www.cnblogs.com/sexintercourse/p/17010294.html
[3]https://github.com/ststeiger/PdfSharpCore/tree/master
[4]https://www.cnblogs.com/xiaohemiao/p/17997370
[5]https://blog.csdn.net/weixin_43918803/article/details/85344624


http://www.niftyadmin.cn/n/5683945.html

相关文章

分布式数据库——HBase基本操作

启动HBase: 1.启动hadoop,进入hadoop的sbin中 cd /opt/hadoop/sbin/ 2.初始化namenode hdfs namenode -format 3.启动hdfs ./start-all.sh 4.启动hbase cd /opt/hbase/bin ./start-hbase.sh 5.使用jps查看进程 jps 以下图片则是hbase启动成功~ 运行HBase ./hbase sh…

“卷”智能, 从高质量算力开始

算力即国力,这已是产业共识。 当人工智能浪潮席卷全球之际,大家深刻感受到发展算力产业的重要性和紧迫性,高质量的人工智能算力已经与国家竞争、产业升级和企业转型息息相关。 去年,《算力基础设施高质量发展行动计划》的颁布&a…

PHP的guzzlehttp/guzzle库在碰到各种异常时的场景

PHP的guzzlehttp/guzzle库在碰到各种异常时的场景 结论: 经过测试得知 在http状态码为1xx, 2xx, 3xx时, 会在111处输出返回 在http状态码为4xx, 5xx时, 会在222处被捕获 在目标服务不可达或其他异常时会在333处被捕获 测试过程: 用其他程序写个接口, 实现输入什么状态码就返…

ICML 2024 论文分享┆一个简单且通用的交通预测提示调优框架

论文简介 本推文介绍了2024 ICML的优秀论文之一《FlashST: A Simple and Universal Prompt-Tuning Framework for Traffic Prediction》。论文的核心目标是通过整合空间和时间因素,精准地预测和分析交通流量的动态变化。然而,在交通预测领域&#xff0c…

解读 Story Protocol:IP 与区块链的潜力与障碍

撰文:100y.eth 编译:J1N,Techub News 8 月,据 The Block 报道,专注于知识产权(IP)的区块链 Story 宣布完成 a16z Crypto 领投 8000 万美元 B 轮融资,参投方包括 Polychain Capital&…

Nginx反向代理配置支持websocket

一、官方文档 WebSocket proxying 为了将客户端和服务器之间的连接从HTTP/1.1转换为WebSocket,使用了HTTP/1.1中可用的协议切换机制(RFC 2616: Hypertext Transfer Protocol – HTTP/1.1)。 然而,这里有一个微妙之处:由于“升级”…

26 Vue3之unocss原子化

zz前置知识 什么是原子化 CSS 原子化 CSS 是一种 CSS 的架构方式,它倾向于小巧且用途单一的 class,并且会以视觉效果进行命名。 为什么使用 原子化 CSS 传统方案 制作原子化 CSS 的传统方案其实就是提供所有你可能需要用到的 CSS 工具。例如,你可能会用预处理器(这里选…

【Router】路由功能之MAC地址过滤(MAC Filter)功能介绍及实现

MAC地址过滤(MAC Filter) MAC 地址过滤是一种网络安全技术,通过在网络设备(如路由器)上设置规则,允许或阻止特定 MAC 地址的设备连接到网络。其主要作用是增强网络的安全性,防止未经授权的设备接入网络。 MAC Filter工作原理 MAC 地址过滤的工作原理是根据设备…