CentOS 7+环境下PHP使用Imagick+ghostscript将PDF文件转为图片(亲测可用)


如题,今天遇到个业务问题,需要对用户上传的PDF文件转png操作,其实就是个首页预览功能,不细说了。


首先,作为一个懒人,遇到新的问题我首先想的是这个坑我还是不亲自去踩了,机制的google了一发,发现很多人写的教程,大喜。前人艰难填坑后人一路坦途,但是理想和现实总是有差距的,各个博主众说纷纭,还有好几年前的过期博文,按他们铺的路走差点没把自己埋坑里。不得已又自己来踩坑了,我尽量把我的过程写的详细,为后人提供参考,但是我懒,233333,你们懂得。


对于什么是Imagick大家可能比较陌生,但是ImageMagick大家说不定还是有点了解的,imagick其实就是ImageMagick的php扩展,有非官方说法:Imagick的新能比GD要优越不少,博主比较懒,就没去具体测试了,有兴趣的同学可以自己研究一下。


所需文件包百度网盘下载:

链接: https://pan.baidu.com/s/1DsZDGFX6vVwMiOJgt1GReg 提取码: m6eb



相关地址集合:


php官方文档: http://php.net/manual/en/book.imagick.php


ghostscript官网: https://www.ghostscript.com


ImageMagick官方下载地址:https://sourceforge.net/projects/imagemagick/files/


imagick函数中文解释:http://www.jb51.net/article/60161.htm


前提:你会编译安装php,服务器安装了c++、gcc-c++等基本库

命令:yum install gcc-c++



1. 安装ImageMagick

博主通过不为人知的“肮脏”手段拿到了下载地址,直接在服务器上下载了源码包:

下载地址: https://netix.dl.sourceforge.net/project/imagemagick/im7-src/ImageMagick-7.0.7-25.tar.gz


下载命令:

wget https://netix.dl.sourceforge.net/project/imagemagick/im7-src/ImageMagick-7.0.7-25.tar.gz


运行截图如下,我先进入了/home/app目录下(本人将下载的文件同意放在了/root目录下,即root用户的家目录),所以文件也下载在这里

20180316172005401.jpg


下载完成后使用下面的命令解压:


 tar -zxvf ImageMagick-7.0.7-25.tar.gz 


解压完毕后进入该文件夹:

20180316172430230.jpg


在该文件夹下执行命令(默认参数,没有更改)


 ./configure 


执行完了后如下图所示,默认安装路径在/usr/local下

20180316172958681.jpg


执行命令,编译并安装ImageMagick,需要一段时间,不如先来一局农药压压惊。或者你可以另开一个terminal连接服务器开始安装别的东西。


 make && make install


完成之后进入安装文件夹,查看ImageMagick是否工作


 cd /usr/local/bin/


 ./convert -version


结果如下:

image.png


注意:本人执行到 convert -version 命令时,出现了一下的错误,度娘了一番

imagemagick 某些版本安装后报错:error while loading shared libraries: libMagickCore-6.Q16.so.1: cannot open shared object file: No such file or directoryimage.png

执行下面命令即可:

ldconfig /usr/local/lib

然后在执行下面的命令,就得到上图的记过 

convert -version


============ 这段代码,本人没有测试过 =============

如果还是没有得到上图的结果:

后来安装ImageMagick6.8.6总是编译失败:magick/.libs/libMagickCore-6.Q16.so: undefined reference to `jpeg_default_qtables'所以不得不重新编译libjpeg最新版本,下载jpegsrc.v9.tar.gz 

tar -xzvf jpegsrc.v9.tar.gz   

cd jpeg-9  

./configure   

make libdir=/usr/lib64    

make libdir=/usr/lib64 install 

============ 这段代码,本人没有测试过 =============






2. 安装PHP扩展Imagick.so

很遗憾,这不是php官方的标准包,所以没有继承在php源码包里面,我在ext/文件夹下没有找到,不过官方文档给出了下载页面地址:


http://pecl.php.net/package/imagick/download


然而机智的我又直接把扩展包的下载地址贴上来了,方便服务器下载:http://pecl.php.net/get/imagick-3.4.3.tgz


我很懒,命令行在图里,同学自己看了==


20180316174340933.jpg




解压后进入该目录,执行phpize,我希望你能找到你的phpize在哪,如果你是编译安装的话,如果没有软链到/usr/bin/目录下,你可以使用绝对路径调用phpize。


微信图片_20190517143109.png



使用下面命令行配置扩展安装,指定--with-php-config是为了统一管理我的extension.so,如果不指定,你也可以copy到php.ini指定的extension位置,--with-imagick默认是/usr/local如果你没改动的话。


./configure --with-php-config=/usr/local/php7/bin/php-config --with-imagick=/usr/local


注意:上面标红的地址路径,你要修改为你服务器上php-config的实际路径,我用的是宝塔,所以路径是/www/server/php/70/bin/

image.png


修改好对应的路径后就可以执行上面的命令了

image.png





配置完成后 编译安装,是的,又是 make && make install


20180316175443638.jpg


这些路径很重要,有时候自己清楚点比较好


另外,本人在B服务器安装完成时发现(A服务器上安装是没有问题),并没有出现上图中最下面红框信息,而且出现imagick.so并没有成功放置在php扩展目录下(具体原因目前还不清楚,个人分析,可能我的A服务器php是通过编译安装的,B服务器是极速安装的)

我的解决方式:将/imagick-3.4.3/modules目录下的imagick.so(参考上图中最上面的红框中的路径,具体路径以你显示为准)拷贝一份到php扩展目录下(php扩展目录,根据你服务器上php-config文件中配置的目录而定)


安装完了后我们要修改php的配置文件,添加上imagick.so,重启php-fpm


20180316175619180.jpg


修改配置文件,记得保存


20180316175743168.jpg


kill php-fpm主进程 并 重启,这里各个人方法不同,我按我的演示一下:


20180316180004398.jpg


重启完了看看自己的phpinfo吧,已经有了


20180316180223356.jpg


这个时候我们试试pdf转png


20180316180431232.jpg


以失败告终,控制台的测试都失败了别说用php的系统调用了,一样gg,大部分国内博客的教程基本到此为止,然后就开始贴代码了,我特么就想喷一句,代码格式都乱七八糟的,到底是你写的还是copy的?关键时候还是overstack靠谱。看上面截图提示的错误信息:


convert: FailedToExecuteCommand `'gs' -sstdout=%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 '-sDEVICE=pngalpha' -dTextAlphaBits=4 -dGraphicsAlphaBits=4 '-r72x72'  '-sOutputFile=/tmp/magick-26757KhSit2bKyfwa%d' '-f/tmp/magick-26757lL6cdz2j5VDZ' '-f/tmp/magick-26757SnLQ7f7amJLO'' (1) @ error/pdf.c/InvokePDFDelegate/291.


convert: no images defined `%d.png' @ error/convert.c/ConvertImageCommand/3275.



带有gs 开头的命令行执行失败,gs其实就是下面要说的ghostscript




3 安装GhostScript 

官方地址:https://www.ghostscript.com/


使用教程:https://www.ghostscript.com/doc/9.22/Use.htm


官方安装教程: https://www.ghostscript.com/doc/9.22/Install.htm


下载地址: https://www.ghostscript.com/download/gsdnld.html


博主比较懒,不想编译安装了,直接下载了编译后的可执行程序,能有就行,23333


我选的是这个,看起来是免费的屌丝版,能用就行,233333


20180316181141445.jpg


这个下载地址被重定向了好多次,没法直接给你们贴上,不过我传到了我的七牛云上,地址给大家共享下:


https://file.mumov.com/ghostscript-9.22-linux-x86_64.tgz


下载到服务器,解压,进入文件夹:


20180316181439227.jpg


完了之后记得给gs的可执行文件copy一份到/usr/bin目录下,这样就可以全局执行了


20180316181642395.jpg


命令行在图里,懒,不写了


到这里基本上就完成了所有模块的安装,试试pdf转png行不行


2018031618185157.jpg


很好,没有报错,转成了png图片了,下面终于可以写代码了




4.  PHP代码实现pdf转图片

我懒,原谅我直接贴代码了


class ImageMagick{
    private $handler;
    public function __construct()
    {
        $this->handler = new \Imagick();
    }
    /**将pdf转为png图片列表
     * @param $pdf_path string pdf文件的绝对路径
     * @param $out_path string 生成图片存放位置的绝对路径
     * @param int $from int  从第几页开始转
     * @param int $to int 截止于第几页
     * @return array
     * @throws SystemInnerException
     */
    public function convertPdf2Images($pdf_path,$out_path,$from=1,$to=1)
    {
          if(!is_dir($out_path)) mkdir($out_path,755); 

        $this->handler->setResolution(120,120);
        $this->handler->setCompressionQuality(50);
        $this->handler->readImage($pdf_path);
        $pages = count($this->handler);
        if($pages == 0)
            throw new SystemInnerException('empty pdf file!');
        $index = 1;
        $data = [];
        foreach ($this->handler as $k=>$v)
        {
            if($index == $from)
            {
                if($from<=$to) {
                    $v->setImageFormat('jpg');
                    $tmp_name = rand(10,100000) . '.jpg';
                    if ($v->writeImage($out_path.$tmp_name) == true)
                        $data[] = $tmp_name;
                    $index++;
                    $from++;
                }else
                    break;
            }else
                $index++;
        }
        return $data;
    }
}

$im = new ImageMagick();
$result = $im->convertPdf2Images('/这里是绝对文件路径/test.pdf', '图片保存文件夹的绝对路径', 1, 2);
var_dump($result);    // 得到导出的图片数据


好了,到这里终于结束了~~~本人在linux测试之前,一直尝试在Windows上测试使用,但不知道是什么原因,一直没有成功,代码运行到readImage()这步是,会报出404错误,让我一直很费解,哎~~希望有在Windows环境下尝试成功的同学,可以告诉我,让我一解心中的谜团,万分感谢,QQ:135370472~~

image.png


文章大部分内容转载于 https://blog.csdn.net/liangxun0712/article/details/79584016,感谢这位博主给出较为详细的经验分享


暂无评论

发布评论