不可复制的PDF转成双层可复制PDF
有些PDF是通过扫描或者虚拟打印机生成的,这些PDF不可复制里边的内容
市面上的工具一般都是收费或者有水印,所以就萌生了自己搞一个的想法:
使用了以下三个开源库
- PdfiumViewer PDF预览及可编辑PDF的提取
- PDFsharp 生成PDF
- PaddleSharp 对图片OCR识别
大概思路是:
用PdfiumViewer 渲染显示,并转PDF为图片;
使用PaddleSharp 对提取图片的内容及bbox坐标;
把坐标根据缩放比转成相对于PDF的坐标,并使用PDFsharp 重新生成PDF,如需要保持原有格式需要把1转成的图片重新回写到生成的pdf,文字层为ocg层;
实现双层pdf的效果;
读取PDF到到内存流:
private PdfDocument OpenDocument(string fileName)
{
try
{
return PdfDocument.Load(this, new MemoryStream(File.ReadAllBytes(fileName)));
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
}
PDF转图片:
//图片dpi要相对大些,这样ocr识别的更清晰
int dpiX = 96 * 5;
int dpiY = 96 * 5;
var pdfWidth = (int)document.PageSizes[page].Width * 4 / 3;
var pdfHeight = (int)document.PageSizes[page].Height * 4 / 3;
var rotate = PdfRotation.Rotate0;
var flags = PdfRenderFlags.Annotations | PdfRenderFlags.CorrectFromDpi;
using (var image = document.Render(page, pdfWidth, pdfHeight, dpiX, dpiY, rotate, flags)){}
OCR识别:
byte[] sampleImageData = ImageToByte(image);
FullOcrModel model = LocalFullModels.ChineseV3;
using (PaddleOcrAll all = new PaddleOcrAll(model, PaddleDevice.Mkldnn())
{
AllowRotateDetection = true, /* 允许识别有角度的文字 */
Enable180Classification = false, /* 允许识别旋转角度大于90度的文字 */
})
{
// Load local file by following code:
using (Mat src = Cv2.ImDecode(sampleImageData, ImreadModes.Color))
{
PaddleOcrResult result = all.Run(src);
return result;
}
}
图片转成流:
private byte[] ImageToByte(System.Drawing.Image image)
{
MemoryStream ms = new MemoryStream();
if (image == null)
return new byte[ms.Length];
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] BPicture = new byte[ms.Length];
BPicture = ms.GetBuffer();
return BPicture;
}
转换bbox坐标到PDF坐标:bbox坐标是相对于图片的坐标,可以
private System.Drawing.RectangleF ConvertToPDFSize(System.Drawing.RectangleF rectangle, float dpiX, float dpiY, PdfRotation rotate, PdfRenderFlags flags)
{
var width = rectangle.Width;
var height = rectangle.Height;
var x = rectangle.X;
var y = rectangle.Y;
if ((flags & PdfRenderFlags.CorrectFromDpi) != 0)
{
width = (width / dpiX * 72);
height = (height / dpiY * 72);
x = (x / dpiX * 72);
y = (y / dpiY * 72);
}
return new RectangleF(x, y, width, height);
}
bbox坐标框选示例:

由于OCR的限制:转双层pdf只能在x64系统运行,不适用OCR可运行x86和x64,
工具功能:
- 可提取和框选提取可复制和不可复制pdf;
- 可转换不可复制的pdf为双层可复制pdf;
- 可转换不可复制的pdf为可复制pdf;
- 加载图片并提取标注提取内容;
直接下载地址:
https://cloud.189.cn/web/share?code=MZvMb2ZNRbMn(访问码:y9st)
也可按照下放代码自己编译使用,遵循MIT协议
欢迎Start、PR
源码地址:https://github.com/1000374/HM.PdfOcr
不可复制的PDF转成双层可复制PDF的更多相关文章
- PDF转换成DXF文件?PDF转DXF的操作方法
在CAD工作中,经常就需要将绘制完成的图纸文件的格式进行转换,那怎么将PDF文件转换成DXF格式的呢?具体要怎么来进行操作呢?本编教程小编就来教教大家具体操作方法,具体操作如下: 一.工具转换 推荐指 ...
- C# 复制PDF页面到另一个PDF文档
C# 复制PDF页面到另一个PDF文档 有时候我们可能有这样一个需求,那就是把PDF页面从一个PDF文档复制到另一个PDF文档中.由于PDF文档并不像word文档那样好编辑,因此复制也相对没有那么容易 ...
- ABBYY把pdf转换成word的方法
有时候我们在网上下载的资料文献是PDF格式文档,遇到喜欢的字句总忍不住想要收藏起来,但是PDF文档不同于普通的Word文档可以直接进行复制粘贴,需要下载安装相关的编辑工具,才能对文字内容进行编辑.倒不 ...
- 复制pdf文字出来是乱码
PDF文件复制文本为乱码 - longzhinuhou的博客 - CSDN博客 https://blog.csdn.net/longzhinuhou/article/details/83758966 ...
- 如何使用Adobe Reader复制PDF文档上的文字
PDF文档大家常用,但是有没有简单的方法能够提取PDF文档上的文字,然后使用呢?除了将PDF转换成Word,这里介绍一种更为简单实用的方法复制PDF文本文字,Adobe Reader是大家都常用的PD ...
- pdf转换成文本解决格式不统一问题
pdf转换成文本解决格式不统一问题 懒得调OCR服务了,所以快速解决的方法是: pdf转png:https://pdf2png.com/zh/ png转统一格式pdf:adobe acrobat自带增 ...
- C#pdf 切割成图片
引用 using Ghostscript.NET;using Ghostscript.NET.Rasterizer; 需要安装 exe文件 public static GhostscriptVersi ...
- pdf 切割成圖片的方法
/// <summary> /// 将PDF文档转换为图片的方法 /// </summary> /// <param na ...
- Python 将pdf转换成txt(不处理图片)
上一篇文章中已经介绍了简单的python爬网页下载文档,但下载后的文档多为doc或pdf,对于数据处理仍然有很多限制,所以将doc/pdf转换成txt显得尤为重要.查找了很多资料,在linux下要将d ...
- 如何用ABBYY把PDF转换成PPT
在电子科技迅速发展的今天,文件格式转换并不是什么稀罕事,因为现在都是电子化办公,出现很多文件格式,但是不同的场合需要的格式不同,所以常常需要进行文件格式的转换.PDF转换成PPT也是众多文件格式转换中 ...
随机推荐
- Federated Learning003
联邦学习笔记--003 2022.11.28周一 今天主要学习了几篇优秀的博客,补充了一些知识. (一)联邦学习面临的挑战 非独立同分布的数据 有限通信带宽 不可靠和有限的设备 什么是Non-IID( ...
- react项目中使用plop
第一步,安装依赖 npm install plop --dev //或者用yarn yarn add plop --dev 第二步,在package同级目录下新建plopfile.js 这是plop的 ...
- java_web:jdbc里的零碎笔记
name="%"+name+"%"; 这段代码是用于构建SQL语句中的模糊查询条件的,其中name是一个字符串类型的变量,表示查询的关键字. %是通配符,在SQ ...
- SEO相关配置 HTML meta标签总结与属性使用介绍
HTML meta标签总结与属性使用介绍 <!-- 声明文档使用的字符编码 --> <meta charset='utf-8'> <!-- 优先使用 IE 最新版本和 C ...
- 使用netdata 监控Linux 主机
在linux主机上,直接使用下面的命令创建容器即可 docker run -d --name=netdata \ -p 19999:19999 \ -v netdataconfig:/etc/netd ...
- [数据分析与可视化] Python绘制数据地图4-MovingPandas入门指北
MovingPandas是一个基于Python和GeoPandas的开源地理时空数据处理库,用于处理移动物体的轨迹数据.它提供了一组强大的工具,可以轻松地加载.分析和可视化移动物体的轨迹.通过使用Mo ...
- [ansible]常用内置模块
前言 ansible内置了很多模块,常用的并不多,可以通过ansible -l命令列出所有模块,使用 ansible-doc module-name 查看指定模块的帮助文档,例如:ansible-do ...
- 微服务集成seata完成分布式事务,解决数据不一致问题
细心的盆友可能已经发现了,我们的跨行转账并没有保证数据一致性,比如小明扣除了100,但是因为各种问题小红在添加100金额的时候遇到了异常,这个时候数据就出现不一致性 我们可以选择seata来进行分布式 ...
- 【Windows】KMS 激活命令记录
目录 KMS 服务器激活 Office.Visio 推荐使用 office tool plus 部署并配置 KMS 激活 什么是 KMS? KMS 正版与否的区别 总结 KMS 服务器激活 利用 KM ...
- 反汇编ARM程序的技术靠谱吗?——揭秘ARM架构二进制程序的反汇编技术现状
本文系原创,转载请说明出处 Please Subscribe Wechat Official Account:信安科研人,获取更多的原创安全资讯 参考发表在2020年软工顶会ISSTA的论文&l ...