PHP利用ImageMagick實(shí)現(xiàn)PDF、PPT轉(zhuǎn)圖片

最近應(yīng)業(yè)務(wù)需要余舶,需要實(shí)現(xiàn)在線瀏覽 PPT啊鸭、PDF 的功能。搜了一陣匿值,看似好用的微軟 Office Web Viewer 卻有著速度極慢赠制、限制10M大小等麻煩,前端直接使用 pdf.js 也遇到了跨域之類的問題挟憔,索性一不做二不休钟些,把 PPT 和 PDF 都轉(zhuǎn)換成圖片,再分頁傳回給前端绊谭。

去網(wǎng)上搜了一圈政恍,看到了 imagick 這個(gè)擴(kuò)展庫,看了操作好像也是十分地簡單达传,沒想到真的動手做起來遇到了不少的麻煩篙耗。

首先是網(wǎng)上的版本迫筑,即用 PHP 的擴(kuò)展庫 imagick 來實(shí)現(xiàn)。

第一步是要安裝宗弯,我用的是寶塔面板脯燃,在 PHP 的安裝擴(kuò)展中找到了 imagemagick,一鍵安裝蒙保,并沒有再遇到什么問題辕棚,直接就能使用了。后來發(fā)現(xiàn)不少人手動安裝時(shí)遇到了許多問題追他,好像是因?yàn)?ImageMagick 需要 Ghostscript 的支持坟募,后面我也裝了一遍,確實(shí)挺麻煩的邑狸,這里記錄一下我的安裝過程:

我的系統(tǒng)是 CentOS7 的懈糯,在這個(gè)網(wǎng)址下載——https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs923/ghostscript-9.23.tar.gz

上傳到服務(wù)器進(jìn)行解壓,然后安裝单雾;或者直接通過命令行下載安裝(比較慢)赚哗,輸入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硅堆,這里因?yàn)槲沂菍毸苯友b的屿储,沒有手動安裝過,不知道還有沒有坑渐逃。另外够掠,裝完 imagick 之后還需要在 php.ini 中開啟相應(yīng)的擴(kuò)展。

//編譯安裝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

環(huán)境真是開發(fā)過程中最大的敵人茄菊,僅僅只是想把 pdf 轉(zhuǎn)成圖片這么個(gè)小操作疯潭,就得安裝三個(gè)東西,真是麻煩的很面殖。光顧著安裝了竖哩,還不知道這三個(gè)分別是啥呢。這三個(gè)當(dāng)中最核心的是 ImageMagick脊僚,它是第三方的圖片處理軟件相叁,功能強(qiáng)大,可以理解為命令行版本的PS辽幌。然后是 imagick增淹,是php的一個(gè)擴(kuò)展模塊,可以調(diào)用 ImageMagick 提供的API來進(jìn)行圖片操作舶衬。最后是 Ghostscript埠通,是一款可以操作 pdf 的軟件,在這里 ImageMagick 無法直接實(shí)現(xiàn) pdf 文檔到圖片的轉(zhuǎn)換逛犹,需要借助于 Ghostscript 軟件包端辱。

總算差不多了梁剔,終于能夠進(jìn)行開發(fā)了。本以為應(yīng)該很容易就能實(shí)現(xiàn)舞蔽,沒想到踩坑之路才剛剛開始荣病。首先先貼一段根據(jù)網(wǎng)上的代碼修改的代碼。

public function pdfToPng($pdf,$path,$page=-1) {

? ? if (!extension_loaded('imagick') || !file_exists($pdf) || !is_readable($pdf)) {

? ? ? ? return ['ok' => FALSE, 'msg' => '服務(wù)器錯(cuò)誤', 'code' => 2003, 'data' => []];

? ? }

? ? $im = new \Imagick();

? ? //設(shè)置分辨率

? ? $im->setResolution(150, 150);

? ? //設(shè)置壓縮質(zhì)量渗柿,1-100,100為最高

? ? $im->setCompressionQuality(100);

? ? //是否進(jìn)行分頁操作

? ? if ($page == -1) {

? ? ? ? $im->readImage($pdf);

? ? } else {

? ? ? ? $im->readImage($pdf . "[" . $page . "]");

? ? }

? ? foreach ($im as $Key => $Var) {

? ? ? ? //設(shè)置圖片格式

? ? ? ? $Var->setImageFormat('png');

? ? ? ? $filename = $path . md5($Key . time()) . '.png';

? ? ? ? if ($Var->writeImage($filename) == true) {

? ? ? ? ? ? $Return[] = $filename;

? ? ? ? }

? ? }

? ? return $Return;

}

核心代碼其實(shí)很簡單个盆,先實(shí)例化 Imagick 類,然后進(jìn)行一些相應(yīng)的設(shè)置朵栖,最后再通過 writeImage 導(dǎo)出為圖片颊亮。接下來看看效果(第一張為圖片,第二章為原PDF)

一開始我眼瞎陨溅,以為這個(gè)庫只能做到讀取 PDF 中的圖片终惑,文字并不能讀取到。在漫長的百度過程中又把 png 格式改成了 jpg门扇,中間又出現(xiàn)了些奇怪的黑色區(qū)域雹有。后來無意中按出 F12 加上仔細(xì)觀察才發(fā)現(xiàn),原來文字并沒有顯示出來的原因是背景為透明的臼寄。

找到問題之后霸奕,目標(biāo)變得明確了——把背景搞白!在又一陣搜索之后吉拳,找到了一個(gè)廢棄的方法 flattenImages质帅,但是很可惜,它已經(jīng)被官方棄用了留攒,并且沒有明確地說用哪個(gè)函數(shù)代替它临梗。即使這樣,還是不能氣餒稼跳,去搜了搜 它,大概了解到它的功能——合并圖層吃沪!沒錯(cuò)汤善,把我們之前的結(jié)果和一個(gè)空白圖層合并,不就能達(dá)到把背景變成白色的效果了嗎票彪!按照這種思路红淡,繼續(xù)搜索,終于找到了降铸!這里貼一下核心代碼在旱,只需要修改之前代碼中的 foreach 循環(huán)中的內(nèi)容就夠了。

$blankPage = new \Imagick();

//一張白紙推掸,作為背景

$blankPage->newPseudoImage($item->getImageWidth(), $item->getImageHeight(), "canvas:white");

//設(shè)置合并的位置

$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;

}

果不其然驻仅,白色的背景來了!但是就在我歡呼雀躍登渣,想著終于把問題解決了的時(shí)候噪服,又發(fā)現(xiàn)了一點(diǎn)不對勁,這圖片失真也太嚴(yán)重了吧胜茧!稍微放大一點(diǎn)都模糊得不行了粘优。本以為這應(yīng)該不是什么問題,只需要改一改之前提過的分辨率和壓縮質(zhì)量呻顽,結(jié)果發(fā)現(xiàn)雹顺,不論怎么改圖片的分辨率都沒有半點(diǎn)變化。

雖說至此廊遍,問題已經(jīng)勉勉強(qiáng)強(qiáng)地解決了嬉愧,但是這個(gè)分辨率是個(gè)硬傷,肯定不能放著不管昧碉。又在一頓瘋狂的搜索之后英染,我仍然沒能解決,終于被饿,我敗給了時(shí)間四康,放棄了這條路。但于此同時(shí)狭握,一條光明大道逐漸在我眼前明亮起來闪金。之前也提到過,imagick 只是把 ImageMagick 的命令封裝了一下給 PHP 使用而已论颅,那我索性直接繞過 imagick哎垦,直接執(zhí)行 ImageMagick 命令不就好了?一頓操作之后恃疯,果然漏设,成了,終于成了今妄。

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

稍微解釋一下吧郑口,-density 150 指定輸出的分辨率,越大越清晰盾鳞,但是文件也會相應(yīng)地變大犬性。

-background white -alpha remove可以一次命令轉(zhuǎn)換多頁 PDF 成多個(gè)圖片并保持白色背景。

后面兩個(gè)參數(shù)分別是需要被轉(zhuǎn)換的 pdf 文件地址和轉(zhuǎn)成的圖片名腾仅,比如像我這樣寫乒裆,能夠把兩頁的 pdf 文件1.pdf 轉(zhuǎn)成1-0.jpg 和 1-1.jpg 。

接下來是 PPT 轉(zhuǎn)圖片推励。這里要利用 Linux 下的另一個(gè)工具:unoconv鹤耍。unoconv肉迫,全稱為?Universal Office Converter ,是一個(gè)命令行工具惰蜜,可在 LibreOffice/OpenOffice 支持的任意文件格式之間進(jìn)行轉(zhuǎn)換昂拂。

首先是安裝:我的系統(tǒng)是 CentOS7 的,如果是別的系統(tǒng)不適用的話抛猖,還得再去百度一下格侯。

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 的使用也非常的簡單朝墩,舉一個(gè)最簡單的例子:

unoconv -f new.pdf old.ppt

雖然轉(zhuǎn)換十分的簡單,只需要一個(gè)指令伟姐,但是這里還有一個(gè)隱藏的小坑——Linux 下和 Windows 下的字體文件不同收苏,很多 Windows 有但是 Linux 并沒有,這就會導(dǎo)致轉(zhuǎn)換之后出現(xiàn)文字亂碼愤兵、排版出錯(cuò)等問題鹿霸,解決方案就是,把 Windows 下的字體拷一份到 Linux 下秆乳。

1懦鼠、找到Windows下的這個(gè)目錄:C:\Windows\Fonts,把里面的文件拷到Linux下的/usr/share/fonts/ 下屹堰,最好新建一個(gè)目錄肛冶,再放在里面,方便管理扯键。

2睦袖、進(jìn)入目錄,執(zhí)行指令荣刑,比如說我新建的目錄叫win

cd /usr/share/fonts/win

mkfontscale

mkfontdir? ? ? ? ? ? //這兩條命令是生成字體的索引信息

fc-cache -fv? ? ? ? //更新字體緩存

安裝好字體之后扣泊,再執(zhí)行一次轉(zhuǎn)換指令,應(yīng)該不會有什么大問題了嘶摊。

另外,如果你有興趣评矩,或者是有問題想要與我探討叶堆,歡迎來訪問我的博客:https:mu-mu.cn/blog

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市斥杜,隨后出現(xiàn)的幾起案子虱颗,更是在濱河造成了極大的恐慌沥匈,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忘渔,死亡現(xiàn)場離奇詭異高帖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)畦粮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門散址,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宣赔,你說我怎么就攤上這事预麸。” “怎么了儒将?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵吏祸,是天一觀的道長。 經(jīng)常有香客問我钩蚊,道長贡翘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任砰逻,我火速辦了婚禮鸣驱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诱渤。我一直安慰自己丐巫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布勺美。 她就那樣靜靜地躺著递胧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赡茸。 梳的紋絲不亂的頭發(fā)上缎脾,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音占卧,去河邊找鬼遗菠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛华蜒,可吹牛的內(nèi)容都是我干的辙纬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叭喜,長吁一口氣:“原來是場噩夢啊……” “哼贺拣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤譬涡,失蹤者是張志新(化名)和其女友劉穎裳凸,沒想到半個(gè)月后秘蛇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年哼拔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猖腕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刃宵。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逊脯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拾酝,到底是詐尸還是另有隱情燕少,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布蒿囤,位于F島的核電站客们,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏材诽。R本人自食惡果不足惜底挫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脸侥。 院中可真熱鬧建邓,春花似錦、人聲如沸睁枕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽外遇。三九已至注簿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跳仿,已是汗流浹背诡渴。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菲语,地道東北人妄辩。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像山上,于是被迫代替她去往敵國和親眼耀。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容