失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > PHP利用ImageMagick实现PDF PPT转图片

PHP利用ImageMagick实现PDF PPT转图片

时间:2022-06-30 16:38:59

相关推荐

PHP利用ImageMagick实现PDF PPT转图片

最近应业务需要,需要实现在线浏览 PPT、PDF 的功能。搜了一阵,看似好用的微软 Office Web Viewer 却有着速度极慢、限制10M大小等麻烦,前端直接使用 pdf.js 也遇到了跨域之类的问题,索性一不做二不休,把 PPT 和 PDF 都转换成图片,再分页传回给前端。

去网上搜了一圈,看到了 imagick 这个扩展库,看了操作好像也是十分地简单,没想到真的动手做起来遇到了不少的麻烦。

首先是网上的版本,即用 PHP 的扩展库 imagick 来实现。

第一步是要安装,我用的是宝塔面板,在 PHP 的安装扩展中找到了 imagemagick,一键安装,并没有再遇到什么问题,直接就能使用了。后来发现不少人手动安装时遇到了许多问题,好像是因为 ImageMagick 需要 Ghostscript 的支持,后面我也装了一遍,确实挺麻烦的,这里记录一下我的安装过程:

我的系统是 CentOS7 的,在这个网址下载——/ArtifexSoftware/ghostpdl-downloads/releases/download/gs923/ghostscript-9.23.tar.gz

上传到服务器进行解压,然后安装;或者直接通过命令行下载安装(比较慢),输入gs --version 查看是否成功安装。

//编译安装# wget -c /ArtifexSoftware/ghostpdl-downloads/releases/download/gs923/ghostscript-9.23.tar.gz# tar xzvf ghostscript-9.23.tar.gz# cd ghostscript-9.23# ./configure && make && make install//直接yum安装yum -y install ghostscrip

之后是安装 ImageMagick 和 imagick,这里因为我是宝塔直接装的,没有手动安装过,不知道还有没有坑。另外,装完 imagick 之后还需要在 php.ini 中开启相应的扩展。

//编译安装ImageMagick# tar xf ImageMagick-6.8.9-9.tar.gz# cd ImageMagick-6.8.9-9# ./configure --prefix=/usr/local/imagemagick# make && make install//直接yum安装# yum install ImageMagick//编译安装imagick# tar -xf imagick-3.2.0RC1.tgz# cd imagick-3.2.0RC1# /usr/local/php/bin/phpize# ./configure --with-php-config=/usr/local/php/bin/php-config --with-imagick=/usr/local/imagemagick# make && make install

环境真是开发过程中最大的敌人,仅仅只是想把 pdf 转成图片这么个小操作,就得安装三个东西,真是麻烦的很。光顾着安装了,还不知道这三个分别是啥呢。这三个当中最核心的是 ImageMagick,它是第三方的图片处理软件,功能强大,可以理解为命令行版本的PS。然后是 imagick,是php的一个扩展模块,可以调用 ImageMagick 提供的API来进行图片操作。最后是 Ghostscript,是一款可以操作 pdf 的软件,在这里 ImageMagick 无法直接实现 pdf 文档到图片的转换,需要借助于 Ghostscript 软件包。

总算差不多了,终于能够进行开发了。本以为应该很容易就能实现,没想到踩坑之路才刚刚开始。首先先贴一段根据网上的代码修改的代码。

public function pdfToPng($pdf,$path,$page=-1) {if (!extension_loaded('imagick') || !file_exists($pdf) || !is_readable($pdf)) {return ['ok' => FALSE, 'msg' => '服务器错误', 'code' => , 'data' => []];}$im = new \Imagick();//设置分辨率$im->setResolution(150, 150);//设置压缩质量,1-100,100为最高$im->setCompressionQuality(100);//是否进行分页操作if ($page == -1) {$im->readImage($pdf);} else {$im->readImage($pdf . "[" . $page . "]");}foreach ($im as $Key => $Var) {//设置图片格式$Var->setImageFormat('png');$filename = $path . md5($Key . time()) . '.png';if ($Var->writeImage($filename) == true) {$Return[] = $filename;}}return $Return;}

核心代码其实很简单,先实例化 Imagick 类,然后进行一些相应的设置,最后再通过 writeImage 导出为图片。接下来看看效果(第一张为图片,第二章为原PDF)

一开始我眼瞎,以为这个库只能做到读取 PDF 中的图片,文字并不能读取到。在漫长的百度过程中又把 png 格式改成了 jpg,中间又出现了些奇怪的黑色区域。后来无意中按出 F12 加上仔细观察才发现,原来文字并没有显示出来的原因是背景为透明的。

找到问题之后,目标变得明确了——把背景搞白!在又一阵搜索之后,找到了一个废弃的方法 flattenImages,但是很可惜,它已经被官方弃用了,并且没有明确地说用哪个函数代替它。即使这样,还是不能气馁,去搜了搜 它,大概了解到它的功能——合并图层!没错,把我们之前的结果和一个空白图层合并,不就能达到把背景变成白色的效果了吗!按照这种思路,继续搜索,终于找到了!这里贴一下核心代码,只需要修改之前代码中的 foreach 循环中的内容就够了。

$blankPage = new \Imagick();//一张白纸,作为背景$blankPage->newPseudoImage($item->getImageWidth(), $item->getImageHeight(), "canvas:white");//设置合并的位置$blankPage->compositeImage($item, \Imagick::COMPOSITE_ATOP, 0, 0);//合并!$blankPage = $blankPage->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);$filename = str_replace('.pdf', '-' . $key . '.jpg', $pdfStr);if ($blankPage->writeImage($filename) == true) {$result[] = $filename;}

果不其然,白色的背景来了!但是就在我欢呼雀跃,想着终于把问题解决了的时候,又发现了一点不对劲,这图片失真也太严重了吧!稍微放大一点都模糊得不行了。本以为这应该不是什么问题,只需要改一改之前提过的分辨率和压缩质量,结果发现,不论怎么改图片的分辨率都没有半点变化。

虽说至此,问题已经勉勉强强地解决了,但是这个分辨率是个硬伤,肯定不能放着不管。又在一顿疯狂的搜索之后,我仍然没能解决,终于,我败给了时间,放弃了这条路。但于此同时,一条光明大道逐渐在我眼前明亮起来。之前也提到过,imagick 只是把 ImageMagick 的命令封装了一下给 PHP 使用而已,那我索性直接绕过 imagick,直接执行 ImageMagick 命令不就好了?一顿操作之后,果然,成了,终于成了。

$command = 'convert -density 150 -background white -alpha remove '.$pdfStr.' '.str_replace('.pdf', '.jpg',$pdfStr);exec($command);

稍微解释一下吧,-density 150 指定输出的分辨率,越大越清晰,但是文件也会相应地变大。

-background white -alpha remove可以一次命令转换多页 PDF 成多个图片并保持白色背景。

后面两个参数分别是需要被转换的 pdf 文件地址和转成的图片名,比如像我这样写,能够把两页的 pdf 文件1.pdf 转成1-0.jpg 和 1-1.jpg 。

接下来是 PPT 转图片。这里要利用 Linux 下的另一个工具:unoconv。unoconv,全称为Universal Office Converter ,是一个命令行工具,可在 LibreOffice/OpenOffice 支持的任意文件格式之间进行转换。

首先是安装:我的系统是 CentOS7 的,如果是别的系统不适用的话,还得再去百度一下。

1、安装libreoffice:yum install -y libreoffice.x86_642、下载或者克隆unoconv:wget /unoconv/unoconv/archive/master.zip3、解压并安装:unzip master.zipcd unoconv-master/make install

就这样简简单单的三步,unoconv 就安装完了。unoconv 的使用也非常的简单,举一个最简单的例子:

unoconv -f new.pdf old.ppt

虽然转换十分的简单,只需要一个指令,但是这里还有一个隐藏的小坑——Linux 下和 Windows 下的字体文件不同,很多 Windows 有但是 Linux 并没有,这就会导致转换之后出现文字乱码、排版出错等问题,解决方案就是,把 Windows 下的字体拷一份到 Linux 下。

1、找到Windows下的这个目录:C:\Windows\Fonts,把里面的文件拷到Linux下的/usr/share/fonts/ 下,最好新建一个目录,再放在里面,方便管理。2、进入目录,执行指令,比如说我新建的目录叫wincd /usr/share/fonts/winmkfontscalemkfontdir //这两条命令是生成字体的索引信息fc-cache -fv //更新字体缓存

安装好字体之后,再执行一次转换指令,应该不会有什么大问题了。

另外,如果你有兴趣,或者是有问题想要与我探讨,欢迎来访问我的博客:https:mu-/blog

如果觉得《PHP利用ImageMagick实现PDF PPT转图片》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。