如何在PHP中用Imagick将彩色PDF转为黑白PDF(适配Twilio传真)
将彩色PDF转换为纯黑白(传真用)的PHP Imagick实现
我来帮你把找到的命令行逻辑转换成纯PHP Imagick代码,不用依赖shell_exec,同时也聊聊Twilio的处理思路,完全满足你在服务器端预览的需求。
对应命令行的PHP Imagick实现
你找到的几个convert命令都可以用Imagick的原生API实现,下面逐个对应:
1. 高分辨率转PNG(对应convert -density 288 in.pdf -resize 25% out.png)
这个命令的核心是用高分辨率读取PDF再缩小,保证清晰度,PHP实现如下:
$imagick = new Imagick(); // 先设置读取PDF的分辨率(对应-density 288) $imagick->setResolution(288, 288); // 读取PDF文件 $imagick->readImage('path/to/in.pdf'); // 遍历处理每一页(PDF可能有多页) foreach ($imagick as $page) { // 缩小到原尺寸的25%(对应-resize 25%) $page->resizeImage( $page->getImageWidth() * 0.25, $page->getImageHeight() * 0.25, Imagick::FILTER_LANCZOS, // 用Lanczos滤镜保证缩放清晰度 1 ); } // 输出为PNG $imagick->writeImage('path/to/out.png'); // 记得释放资源 $imagick->destroy();
2. 生成传真压缩的纯黑白PDF(对应convert -density 600 in.pdf -threshold 15% -type bilevel -compress fax out.pdf)
这是最适合传真的方案,生成的PDF用传真压缩,体积小且符合纯黑白要求:
$imagick = new Imagick(); $imagick->setResolution(600, 600); $imagick->readImage('path/to/in.pdf'); foreach ($imagick as $page) { // 设置阈值15%(对应-threshold 15%),Quantum是Imagick的色彩最大值,0.15*Quantum就是15%的阈值 $page->thresholdImage(0.15 * Imagick::getQuantum()); // 设置为双色调(纯黑白,对应-type bilevel) $page->setImageType(Imagick::IMAGETYPE_BILEVEL); // 启用传真压缩(对应-compress fax),大幅减小文件体积 $page->setImageCompression(Imagick::COMPRESSION_FAX); } $imagick->writeImage('path/to/out.pdf'); $imagick->destroy();
3. 高分辨率转纯黑白TIFF(对应convert -density 288 image.pdf -resize 25% -threshold 50% -type bilevel image.tiff)
如果需要TIFF格式的输出,代码如下:
$imagick = new Imagick(); $imagick->setResolution(288, 288); $imagick->readImage('path/to/image.pdf'); foreach ($imagick as $page) { $page->resizeImage( $page->getImageWidth() * 0.25, $page->getImageHeight() * 0.25, Imagick::FILTER_LANCZOS, 1 ); // 50%阈值,适合对比度适中的文档 $page->thresholdImage(0.5 * Imagick::getQuantum()); $page->setImageType(Imagick::IMAGETYPE_BILEVEL); } $imagick->writeImage('path/to/image.tiff'); $imagick->destroy();
Twilio的处理方式
根据你更新的内容,Twilio是通过quantizeImage来实现纯黑白转换的,核心是把图像量化为仅2种灰度色(黑和白),调整参数后的代码更适合传真:
$img = new Imagick('path/to/document.pdf'); $img->quantizeImage( 2, // 只保留2种颜色(黑、白) Imagick::COLORSPACE_GRAY, // 基于灰度空间处理 1, // 深度树设为1,足够区分黑白 true, // 启用抖动,让文字和图像的过渡更自然,提升传真可读性 false // 关闭误差校正 ); $img->writeImage('path/to/output.png'); $img->destroy();
这种方式和阈值处理的区别在于:量化会自动根据图像的灰度分布来分配黑白,而阈值是固定一个分界点。如果你的文档有不同深浅的内容,量化可能会更灵活,更符合传真的可读性要求。
小提示
- 处理多页PDF时,一定要遍历每一页单独处理,否则可能只有第一页生效。
- 传真的标准分辨率是204x96(普通)或204x192(精细),你可以根据需求调整
setResolution的参数和缩放比例,比如用204 DPI直接读取,就不需要再缩放了。 - 用
COMPRESSION_FAX生成的PDF体积更小,更适合传真传输,和Twilio的要求匹配度更高。
内容的提问来源于stack exchange,提问作者senty




