本文介绍如何使用.NET和PdfPig库创建一个简单实用的PDF图片提取工具,解决日常工作中从PDF提取图片的痛点,实现"拖放即用"的便捷体验。
前段时间有个朋友向我吐槽:他在工作中为了从PDF文件中提取图片,不得不一页页截图,效率低下且图片质量受损。确实,很多非技术背景的用户在面对这种需求时,往往只能采用这种"笨办法"。
怀念那个满是绿色工具的时代——无需上传、没有隐私之忧、免费实用,解决实际问题从不靠功能臃肿的商业软件。如今,不如自己动手,找回那份纯粹的便捷。
本文将结合我的实际经验,分享如何使用.NET创建一个简单实用的PDF图片提取工具,帮助大家告别繁琐的截图操作。
在.NET生态中,处理PDF的库有不少,我最终选择了PdfPig,主要基于以下几点考虑:
当然,也不要过于担心技术选型的复杂性。对于初学者来说,选择一个成熟稳定的库能够大大降低开发难度。更重要的是,PdfPig的文档相对完善,社区活跃,这对于我们快速上手非常有帮助。
下面是我实现的完整代码,代码量不大但功能完整:
using UglyToad.PdfPig;
// 获取传入的pdf参数
if (args.Length == 0)
{
Console.WriteLine("请传入PDF文件路径");
return;
}
var pdfPath = args[0];
if (string.IsNullOrEmpty(pdfPath))
{
Console.WriteLine("请传入PDF文件路径");
return;
}
if (!File.Exists(pdfPath))
{
Console.WriteLine("PDF文件不存在");
return;
}
// 获取PDF文件名
var pdfFileName = Path.GetFileNameWithoutExtension(pdfPath);
using PdfDocument document = PdfDocument.Open(pdfPath);
int imginx = 1;
foreach (var page in document.GetPages())
{
var images = page.GetImages();
foreach (var image in images)
{
var isjpeg = image.RawBytes[0] == 255;
var imagePath = Path.Combine(Path.GetDirectoryName(pdfPath) ?? string.Empty,
$"{pdfFileName}_{imginx}.{(isjpeg ? "jpg" : "png")}");
using (var stream = File.Create(imagePath))
{
using MemoryStream ms = new(image.RawBytes.ToArray());
ms.CopyTo(stream);
}
Console.WriteLine($"提取图片成功: {imagePath}");
imginx++;
}
}
var isjpeg = image.RawBytes[0] == 255;
这里使用了一个简单的启发式方法:检查图片数据的第一个字节是否为255。这是因为JPEG文件通常以0xFF开头(JPEG文件起始标记)。虽然这种方法在大多数情况下有效,但并不是100%可靠。
更严谨的做法是检查文件头签名:
private static string GetImageFormat(byte[] bytes)
{
// JPEG: FF D8 FF
if (bytes.Length > 2 && bytes[0] == 0xFF && bytes[1] == 0xD8 && bytes[2] == 0xFF)
return "jpg";
// PNG: 89 50 4E 47
if (bytes.Length > 3 && bytes[0] == 0x89 && bytes[1] == 0x50 &&
bytes[2] == 0x4E && bytes[3] == 0x47)
return "png";
// 默认处理为PNG
return "png";
}
最后我们打包为独立的可执行文件,方便用户直接使用:
dotnet publish -c Release -r win-x64 --self-contained true
打包完成后,用户只需要将PDF文件拖到程序上,黑框一闪,PDF中的图片就被提取出来了。没有复杂的操作,没有额外的依赖,真正做到了"拖放即用"。
有个程序员的朋友就是这么酷——从"截图苦工"到"一键提取"。
这个工具虽然代码量不大,但切实解决了实际问题。希望这个工具对您也有帮助!