PHP利用ImageMagick实现PDF、PPT转图片

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

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

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

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

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

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

//编译安装

# wget -c https://github.com/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' => 2003, '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_64

2、下载或者克隆unoconv:

wget https://github.com/unoconv/unoconv/archive/master.zip

3、解压并安装:

unzip master.zip

cd 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、进入目录,执行指令,比如说我新建的目录叫win

cd /usr/share/fonts/win

mkfontscale

mkfontdir            //这两条命令是生成字体的索引信息

fc-cache -fv        //更新字体缓存

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容