公司动态
开源工具链搞定图片PDF音视频转换:本地命令行指南
为了一次 PDF 转 Word或者一段视频转成 MP3专门去开在线转换站会员我经历过不止一次。后来发现日常遇到的图片、PDF、音视频格式转换大部分都能在本地用开源工具完成不上传文件、不排队、不按页数限制、不因文件太大被拒绝。这篇不推荐什么所谓的一次性“小众神器”而是把真正能落地的开源工具链按场景拆开讲图片用什么PDF 用什么音视频用什么以及为什么我不建议你继续把格式转换当成付费需求。这些工具单个拿出来都不算冷门但绝大多数普通用户不会把它们组合成一套“转换工作站”。原因是它们都是命令行工具没有那种“打开即用”的漂亮界面。但一旦你接受命令行这个设定转换效率会明显提升尤其是批量任务右键点几百次鼠标选格式这种事实际上没必要重复做。下面我按实际使用顺序把环境准备、图片转换、PDF 处理、音视频转换、批量任务设计和边界条件一条条拆开。1. 在找工具之前先判断你的转换需求属于哪一类1.1 四类高频转换场景处理逻辑完全不同格式转换听起来是一个需求实际上至少可以拆成四类每类对应的工具和处理思路都不一样。第一类是图片格式互转。比如把 PNG 转 JPG、把 WebP 转 JPG、把 SVG 栅格化、把一堆图片压缩后发到群里。这类任务的核心不是“转换格式”本身而是“图片要不要压缩”“要不要缩放”“要不要批量处理”。很多在线工具能转单张但批量上传时就会开始限速、限数量、让你开会员。第二类是 PDF 处理。PDF 的需求非常杂压缩 PDF 大小、合并多个 PDF、拆分某几页、提取 PDF 里的图片、把 PDF 转成 Word、把扫描版 PDF 变成可搜索文本。这些需求看起来都叫“PDF”但底层处理方式完全不同。压缩要重新编码页面对象合并是页面级操作转 Word 则要先解析 PDF 内容流再重组文档结构。第三类是音视频转换。常见的有把 m4s 缓存文件转成 mp4把 mp4 提取音频为 mp3把一部视频压小一点再传到某个平台把 mkv 封装改成 mp4。音视频转换的核心是编码和解封装。很多看似转失败的情况其实是源文件和目标容器、编码器不匹配。第四类是文档互转。比如 PDF 转 Word、Word 转 PDF、Markdown 转 PDF。这类任务往往不只是一个格式转换还涉及排版、字体、表格、图片位置。开源方案能做但效果取决于源文档的规范程度。1.2 为什么本地开源方案比在线转换站更靠谱在线转换站的优势是方便不用装软件。但实际用多了就会发现几个问题。第一是隐私。你要把 PDF、视频、图片上传到对方服务器。合同、身份证照片、内部资料这类文件上传前最好多想想。第二是限制。免费额度通常有文件大小、转换次数、每日数量限制。真正要批量转时它们会频繁弹出“升级会员”“解锁更多文件”。第三是排队和速度。文件越大越容易排队或者在中途超时失败。本地转换没有这个问题你的 CPU、内存、磁盘直接决定速度。第四是可重复性。本地命令行工具稳定之后下一次批量处理只需要改几条路径和参数。在线工具每次都要重新上传、重新等、重新下载。如果你偶尔只转一次小文件在线转换站没问题。但如果你要处理几十张图片、几十个 PDF、几段视频本地开源工具链的价值立刻就体现出来了。2. 本地开源转换工具链怎么选不需要全部安装2.1 按平台准备环境最常见的系统是 Windows、macOS、Linux。安装方式有差异但核心命令基本一致。Windows 上推荐直接到各工具官网下安装包或者在 PowerShell 里用 winget 安装。winget 的好处是能一次装多个并自动加入环境变量。例如winget install GnuWin32.image不过实际上没有统一的 winget 包名更稳妥的方式是分别搜索。我把四件核心工具列一下。macOS 用户优先用 Homebrewbrew install ffmpeg imagemagick ghostscript libreoffice poppler qpdfLinux 用户根据发行版不同使用 apt、dnf 或 pacman。Debian/Ubuntu 常见命令sudo apt update sudo apt install ffmpeg imagemagick ghostscript libreoffice poppler-utils qpdf不要一上来把十几个包全装了。你只需要先装当前场景必需的跑通一条任务再按需添加。2.2 四件核心工具和职责边界我平时最固定的组合是这四件工具负责场景典型命令不适合做什么FFmpeg音视频转码、提取音频、视频压缩ffmpeg -i input.m4s -c copy output.mp4不适合做图片精修ImageMagick图片格式转换、缩放、拼接、压缩magick input.png -resize 50% output.jpg不适合做复杂矢量编辑GhostscriptPDF 压缩、PDF 合并、PDF 页面重组gs -sDEVICEpdfwrite -o out.pdf in.pdf不适合转 Word效果很不可控LibreOffice文档互转尤其是 PDF 转 Word、Word 转 PDFsoffice --headless --convert-to docx input.pdf对扫描版 PDF 基本无效另外两个经常用到的补充工具poppler-utils 提供 pdftotext、pdfimages、pdfuniteqpdf 做 PDF 拆页、加密解密和结构修复。两者的定位不同但都值得装。2.3 验证安装是否成功装完之后先运行版本命令而不是直接开始转文件。这一步能过滤掉环境变量和安装路径的问题。ffmpeg -version magick -version gswin64c --version soffice --versionWindows 上如果命令提示符或 PowerShell 提示“不是内部或外部命令”说明安装目录没有加入 PATH。常见解决办法重新打开终端或者手动把工具的 bin 目录加入系统环境变量。也有一种情况是安装时没勾选“添加到 PATH”选项需要重装或手动配置。这里插一个容易踩的坑ImageMagick 在老版本里的命令是 convert新版改成了 magick。Windows 系统本身自带一个 convert.exe是磁盘转换工具。如果你在命令行里习惯性输入 convert很可能触发的是 Windows 自带的那个而不是 ImageMagick报错会非常奇怪。所以建议统一使用 magick。注意先在终端里把每个工具的版本号确认一遍再做后续操作。版本号能正常输出说明这条链路已经通了。3. 图片格式转换批量改格式、缩放、压缩、拼接一页讲清3.1 单张转换和常见格式ImageMagick 处理图片格式转换很直接。单张 PNG 转 JPG 是这样magick input.png -quality 90 output.jpg这里的 -quality 参数控制 JPG 压缩质量。值越高画质越好文件也越大。常见取值范围是 70 到 95。90 适合一般分享80 适合发网页70 适合存储和快速传输。如果你要把 HEIC 转成 JPG先确认安装版本是否带了 heic 解码支持。Win 官方版很多时候不支持Linux 上要装 libheif。如果转不了大可以绕道用 FFmpegffmpeg -i input.heic output.jpgFFmpeg 的 HEIC 支持也取决于编译参数但通常比 ImageMagick 默认版更容易碰到可用版本。WebP 转 JPG、PNG 转 WebP 也类似magick input.webp output.jpg magick input.png -quality 80 output.webpWebP 在网页场景里压缩率通常比 JPG 好但如果你只是本地存档JPG 和 PNG 兼容性更稳。3.2 批量转换Windows 和 Linux 写法批量是开源工具链的强项。单张转换只需要一条命令批量也只是加一层循环而已。在 Windows 命令提示符里把当前目录所有 PNG 转成 JPGfor %f in (*.png) do magick %f %~nf.jpg这里 %f 是循环变量%~nf 表示去掉扩展名后的文件名。如果你把这个命令写进 .bat 文件循环变量要改成 %%f 和 %%~nf。Linux 或 macOS 的 bash 里写法类似for f in *.png; do magick $f ${f%.png}.jpg; done这句命令对新手来说有点绕但它的逻辑很清晰遍历当前目录下所有 .png 文件每次取一个文件用 ImageMagick 转成同名 .jpg。批量缩放并压缩一张或多张图可以加尺寸参数magick input.jpg -resize 1920x1920 -quality 80 output.jpg在批量场景中我会建议先对 1 到 3 个文件做一次单条测试确认输出尺寸和清晰度符合预期再放开循环。这样能避免几百个文件转完之后才发现尺寸参数不对还得全部重来。3.3 长图拼接和 SVG 栅格化把多张图片垂直拼成一张长图也是常见需求。ImageMagick 的 append 语法magick 1.png 2.png 3.png -append output.png这是垂直拼接。旁边再加一个 -append 是垂直默认水平拼接可以用 appendmagick 1.png 2.png 3.png append output.png要注意每张图片尺寸不一致时拼接结果可能有空白或自动拉伸。一般会先统一宽度或高度或者在拼接时加 -resize 参数。SVG 转 PNG 也很常见。SVG 是矢量图直接转 PNG 时分辨率取决于 -density 参数magick -density 150 input.svg -resize 1024x1024 output.pngdensity 调大一点矢量图栅格化后的细节才够。不要拿着默认 72 DPI 直接转小尺寸 SVG 转出来的 PNG 会糊。3.4 图片转换常见报错和安全策略ImageMagick 处理 PDF 或部分格式时报错“attempt to perform an operation not allowed by the security policy”这是安全策略限制。新版默认的 policy.xml 会阻止某些操作尤其是 PDF 和 PS 处理。如果你确实需要 ImageMagick 直接转 PDF 或读取 PDF可以编辑 policy.xml把对应 PDF 的 rights 改成 read|write或者单独放开。但我不建议轻易改安全策略。普通图片转换完全不会触发这个限制。只有你要把 PDF 转成图片时才需要调整。而且 PDF 转图片我更推荐用 Ghostscript 或 poppler 的 pdftoppm而不是 ImageMagick。原因很简单ImageMagick 对 PDF 的处理依赖 Ghostscript 作为后端中间多一层出问题时不好判断是哪个环节坏了。直接用 Ghostscript 出图片更可控。4. PDF 处理合并、拆页、压缩、提取图片别急着充值PDF 相关需求是“付费转换器”最常见的盈利点。很多人到这一步就直接付费了其实开源工具能覆盖大部分基础操作。4.1 PDF 压缩Ghostscript 是最容易忽略的高效工具PDF 压缩是刚需。几百 MB 的 PDF 发送到微信或邮件时经常被拒收而 Ghostscript 一行命令就能压得很明显。gs -sDEVICEpdfwrite -dCompatibilityLevel1.5 -dPDFSETTINGS/ebook -dNOPAUSE -dBATCH -sOutputFileoutput.pdf input.pdf-dPDFSETTINGS 是压缩质量档位档位典型用途文件大小趋势/screen屏幕预览最小/ebook普通阅读中等/printer打印输出偏大/prepress专业印刷最大实际测试时同一个文件用 /ebook 和 /printer体积可能相差两三倍。如果你的 PDF 里面有大量图片压缩效果会更明显。如果 PDF 本身就以矢量文字为主压缩空间可能不大。Windows 上的命令是把 gs 换成 gswin64cgswin64c -sDEVICEpdfwrite -dCompatibilityLevel1.5 -dPDFSETTINGS/ebook -dNOPAUSE -dBATCH -sOutputFileoutput.pdf input.pdf压缩后一定要打开文件看一眼确认文字没有变糊、图片没有缺块、页数没有减少。命令行工具不报错不代表输出质量没问题。4.2 PDF 合并、拆页、提取文本和图片合并多个 PDF 用 pdfunite 最简单pdfunite 1.pdf 2.pdf 3.pdf merged.pdf如果你需要指定页面范围合并用 qpdf 更灵活qpdf --empty --pages 1.pdf 1-3 2.pdf 4-6 -- merged.pdf这条命令表示从 1.pdf 取第 1 到 3 页从 2.pdf 取第 4 到 6 页合并成一个新的 merged.pdf。拆页也可以用 qpdfqpdf --pages input.pdf 1-10 -- first10.pdf提取 PDF 里的纯文本用 poppler-utils 的 pdftotextpdftotext input.pdf output.txt这个命令只适合文本型 PDF。扫描版 PDF 里没有文本层pdftotext 出来的是空白这时候需要 OCR不是简单转换能解决的问题。提取 PDF 里的图片可以用 pdfimagespdfimages -png input.pdf image命令会在当前目录生成 image-001.png、image-002.png 这样的文件。这个命令对扫描版 PDF 特别有用因为扫描版的“图片”通常就是整页内容。如果追求更精细的控制可以用 Python 加 PyMuPDF。下面是一个提取所有页面图片的示例import fitz doc fitz.open(source.pdf) for page_num in range(len(doc)): page doc.load_page(page_num) images page.get_images(fullTrue) for img_index, img in enumerate(images): xref img[0] pix fitz.Pixmap(doc, xref) if pix.n - pix.alpha 3: pix fitz.Pixmap(fitz.csRGB, pix) pix.save(fpage{page_num1}_{img_index1}.png)运行前需要安装pip install pymupdf这段代码会遍历每一页提取嵌在 PDF 里的图片并按页码保存。它的好处是你可以知道自己提取的是哪一页的图方便后续人工筛查。4.3 PDF 转 Word能转但有前提这是很多人最关心的需求。开源方案里LibreOffice 是一个可选项soffice --headless --convert-to docx input.pdfheadless 表示不启动图形界面convert-to docx 指定输出格式。生成的 docx 文件名默认为 input.docx。但这里我必须把边界说清楚LibreOffice 处理 PDF 转 Word本质上是在重新解析 PDF 的内容流再导入 Writer 排版。对于版式简单的文本 PDF效果还能看对于多栏、复杂表格、图文混排、特殊字体转换结果可能乱掉。扫描版 PDF 因为这个路径根本不识别文字所以会得到一页页图片或者什么内容都无法正常编辑。如果你拿到的 PDF 本身是从 Word 生成的又需要重新编辑还有另一条思路用 PDF 编辑器把页面内容复制出来或者直接用原文档重新导。要是没有原文档只能接受“转出来是近似结果”的现实。如果你的需求是“把扫描版 PDF 变成可编辑 Word”开源方案会复杂很多。要先用 Tesseract 做 OCR把识别出的文本层叠加到 PDF 上再让 LibreOffice 或在线转换工具去转换。流程能跑通但版面还原度通常不如商业工具。这种情况下我认为用商业工具或者人工重新排版浪费时间反而更少。4.4 PDF 处理排查顺序PDF 处理出问题时不要上来就怀疑命令写错按这个顺序排查先确认输入 PDF 是否损坏。用 qpdf 检查结构qpdf --check input.pdf如果输出里有 Error 或 Warnings先修复文件。确认 PDF 是文本型还是扫描版。把某一页放大看或者用 pdftotext 输出文本。如果文本为空后续所有“转 Word”“提取文字”类操作都会失败。确认文件路径没有特殊字符。命令行里中文文件名、英文括号、空格都可能导致解析失败。优先处理前把文件复制成简单名字。确认磁盘空间。PDF 压缩和拆页过程中临时文件可能很大。尤其是几百 MB 的 PDF磁盘剩余空间要留足两倍以上。5. 音视频格式转换FFmpeg 一条命令能覆盖大部分需求5.1 从 m4s、mkv 到 mp4容器转换和重新编码FFmpeg 是音视频转换场景里绕不开的工具。它既能做“封装格式转换”也能做“编码格式转换”两者速度差异非常大。先说封装格式转换。有些客户端缓存或录制的视频是 m4s、mkv、ts、flv 这样的格式在普通播放器里不方便播放。如果视频编码本身已经是 H.264/H.265音频编码是 AAC那么直接用ffmpeg -i input.m4s -c copy output.mp4-c copy 表示不重新编码只把音频流和视频流复制到 mp4 容器里。速度非常快基本是磁盘读写速度。但前提是源文件的编码和 mp4 容器兼容。如果源文件是 VP9 编码或 PCM 音频直接复制到 mp4 可能失败这时需要重新编码。mkv 转 mp4 也可以用ffmpeg -i input.mkv -c copy output.mp4有些 mkv 里有字幕流、多音轨转 mp4 时可能因为字幕格式不兼容而报错。这时可以用 -map 指定要保留的流比如只保留第一条视频流和第一条音频流ffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -c copy output.mp45.2 提取音频mp4 转 mp3 的常见场景把视频里的背景音乐或原声提取出来用 FFmpeg 很容易ffmpeg -i input.mp4 -vn -c:a libmp3lame -qscale:a 2 output.mp3-vn 表示不处理视频流。libmp3lame 是 MP3 编码器。qscale:a 是音频质量参数范围大约是 0 到 9越小质量越高。2 到 4 是比较平衡的选择。如果你希望输出更高质量的音频可以改用 FLAC 或 AAC。假设输入是 AAC想要无损提取可以不重新编码ffmpeg -i input.mp4 -vn -c:a copy output.aac这条命令很快但得到的是裸 AAC 流部分播放器也能识别。如果想封装成 m4affmpeg -i input.mp4 -vn -c:a copy output.m4a5.3 视频压缩和批量转码视频文件太大发不出去这是另一个高频需求。FFmpeg 压缩一般用 H.264ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac output_small.mp4-crf 是质量控制参数。它的值越小画质越高文件越大。23 是通用默认值18 左右接近无损观感28 到 30 文件很小但可能出现画质损耗。-preset 决定编码速度和压缩率的平衡。medium 是默认fast 更快但文件略大slow 更慢但文件更小。批量转码时不要用很激进的多并发方案。FFmpeg 本身就能吃满多核你同时开三四个进程CPU 会长时间满载系统可能卡顿而且散热不好的机器容易降频反而更慢。更稳妥的做法是串行循环或者用 xargs 限制并发数为 2。Linux/macOS 批量转码示例mkdir -p output for f in *.mp4; do ffmpeg -i $f -c:v libx264 -crf 23 -preset medium -c:a aac output/${f%.mp4}_small.mp4 doneWindows 命令提示符里写成for %f in (*.mp4) do ffmpeg -i %f -c:v libx264 -crf 23 -preset medium -c:a aac %~nf_small.mp4注意输出文件名不要和输入文件名一致避免覆盖原文件。我一般会单独建一个 output 目录所有结果集中放一个地方方便检查。5.4 FFmpeg 排查编码器、命名、卡死FFmpeg 报错时先看最后几行不要盯着中间大段滚动日志。常见问题有几种。提示 Unknown encoder libx264说明你的 FFmpeg 编译版本没有包含 H.264 编码器。Windows 官方版一般包含Linux 发行版可能需要安装额外包比如 Ubuntu 上的 ffmpeg 可能缺少 x264装一下sudo apt install libx264-dev或者直接安装完整版 ffmpeg。文件名带空格或特殊字符时一定要用引号包住。英文括号也会导致命令行解析出错。处理大文件时如果命令一直没有结束先打开任务管理器或系统监视器看进程是否还在工作。如果 CPU 使用率很高说明还在编码只是时间长。如果 CPU 已经降为 0大概率是卡住或等待输入需要中断调整参数。监控场景视频或播放器缓存格式有些厂商会使用自定义封装FFmpeg 不一定能直接识别。先用ffprobe input_mystery_file查看它到底是一些什么流。ffprobe 能告诉你编码格式、分辨率、时长、音轨数量。判断清楚之后再决定是 -c copy 还是重新编码。6. 批量任务怎么设计先跑单条再开循环最后做自动化6.1 单条任务验证的重要性很多人一开始就把整个文件夹塞给循环跑结果跑到第十个文件才发现输出目录命名不对或者某个格式不被支持前面的时间全浪费了。我建议所有批量任务都遵守一个顺序先跑一条确认成功再跑两三条确认输出规律最后才放开全部文件。单条验证时重点看三样东西输出文件是否能打开内容是否符合预期命名是否规范。只要这三样没问题再考虑批量。6.2 批量任务的三个关键点命名、失败重试、日志批量转换最常翻车的地方不是命令本身而是文件命名和失败恢复。输出文件名一定要有规律。用源文件名加后缀是最稳妥的比如 input.m4s 转 output.mp4能直接对上。不要统一叫 output.mp4因为循环会互相覆盖最后只剩一个文件。失败重试方面命令行循环遇到单个文件失败默认会继续往下跑还是会中断取决于你写的脚本。如果是简单的 for 循环一条失败后通常继续。但这意味着你可能没注意到某个文件被跳过了。所以日志很重要。Linux/macOS 里可以这样记录日志for f in *.mp4; do echo processing $f ffmpeg -i $f -vn -c:a libmp3lame output.mp3 success.log 21 doneWindows PowerShell 里可以用 Start-Transcript 记录整个会话。我自己的习惯是先把所有文件名列出来全部跑完后比较输入输出文件数量缺失的直接重新处理对应文件。6.3 用 Python 做更复杂的文件整理当转换规则复杂到命令行不好写时用 Python 更靠谱。比如只转换文件大小超过 100MB 的视频或者在 PDF 提取图片时按页码整理目录。伪代码思路是这样的import subprocess from pathlib import Path source_dir Path(source) output_dir Path(output) output_dir.mkdir(exist_okTrue) for video in source_dir.glob(*.mp4): if video.stat().st_size 100 * 1024 * 1024: continue out output_dir / (video.stem _small.mp4) subprocess.run([ ffmpeg, -i, str(video), -c:v, libx264, -crf, 23, -c:a, aac, str(out) ], checkTrue)如果你已经有 Python 基础用这个方式管理批量任务会从容很多。它能处理断点续跑、文件过滤、日志记录、失败重试。这些不是格式转换本身的问题但批量任务真正落地时往往就是这些细节决定体验。7. 别被开源方案劝退的边界这些场景还是得用商业工具7.1 复杂版式 PDF 转 Word 和扫描 PDF 的 OCR开源工具能处理很多 PDF 需求但不等于所有 PDF 需求都能免费搞定。复杂版式的 PDF 转 Word比如有大量文本框、复杂页眉页脚、图文混排LibreOffice 的输出很可能和原版差很远。不是工具不行是 PDF 本身就不是为方便重新编辑而设计的格式。扫描版 PDF 的 OCR 也是类似情况。Tesseract 能识别文字但要达到你想要的准确率和排版还原度需要花时间调语言包、图像预处理、版面分析。这个成本对于“偶尔转一份扫描合同”的人来说实在不划算。我的建议是低频使用文件不敏感时商业转换工具依然合理高频使用文件敏感或者需要批量处理时才适合投入时间配置开源方案。7.2 专业音视频编辑或特定编码需求FFmpeg 可以做转码、裁剪、拼接、提取音轨、加字幕这些事。但如果你要做多轨道剪辑、特效、调色、降噪那需要的是剪映、Premiere、DaVinci Resolve 这类编辑软件不是命令行工具。另外某些编码格式涉及版权授权或商业限制。FFmpeg 编译版本里包含的编码器取决于版权法律和打包策略。你可能会发现某些商业播放器支持的编码FFmpeg 默认不能输出。这不是 FFmpeg 弱而是许可证边界。真要用特定编码器先确认本地环境的许可证和编译选项。7.3 当“时间成本”高于“工具成本”开源方案最大的门槛不是钱而是学习成本。第一次配置环境可能要花半小时第一次写批量脚本可能又要花一小时。如果你今天只有一份文件要转而且五分钟内必须完成那打开在线转换站或者商业工具显然是更理性的选择。判断标准很简单这件事你只做一次用现成工具同一个动作你会重复十次以上学命令行重复一百次以上写自动化脚本。我自己踩过不少次“以为能靠工具结果被工具坑”的亏。最后发现很多问题不是开源工具能力不够而是前置环境和输入材料没有处理干净。文件路径、编码格式、PDF 是否扫描版、FFmpeg 是否带指定编码器这些检查不花多少时间但能省下大量重跑成本。先跑单条、再看日志、再调参数这个顺序对图片、PDF、音视频都适用。把这套习惯带进日常基本就不需要再为普通格式转换充值了。