首頁  >  文章  >  後端開發  >  長微博生成(將html轉換為圖片)原理淺析

長微博生成(將html轉換為圖片)原理淺析

伊谢尔伦
伊谢尔伦原創
2016-12-02 11:02:136104瀏覽

在平時工作上有一些需求,簡單而言就是需要將一些內容產生圖片。簡單的內容透過PhotoShop處理還行,但是類似於有表格等的內容,每次都透過PhotoShop進行處理太浪費時間。網路上有很多類似長微博等的生成工具,生成簡單的圖片還行,但是要使用富文本生成圖片,則多需要money,於是便自己研究了一下基於PHP的實現。

需求及原理

基於PHP,將html內容產生圖片(PNG,JPEG等)

實作方法

1. 直接透過圖形函數產生

可以直接使用PHP中自帶的GD庫或imagick,將文字內容轉換成圖片。這在處理純文字內容的時候是很給力的,但是對於富文本內容來說卻很吃力了,很難處理好。目前開源的有painty等,可以支援p、img等幾個簡單的html標籤。

2. html->pdf->png

該方式即首先將html內容產生pdf文檔,再將pdf文檔轉換成為圖片。

html to pdf:目前較成熟的方案包括tcpdf,HTML2PDF等,其實HTML2PDF也是使用的tcpdf的核心;

pdf to png:可以透過imagick php擴充。

目前基於該種方式的開源程式碼有html to image,其原理如下圖所示。

長微博生成(將html轉換為圖片)原理淺析

核心程式碼為(摘自:http://buffernow.com/html-to-image-php-script/):

//获取某个URL地址的内容
    echo file_get_contents('http://php.cn/');
    //将内容转换成pdf文档
    $html2pdf = new HTML2PDF('P', 'A4');
    $html2pdf->writeHTML($html_content);
    $file = $html2pdf->Output('temp.pdf','F');
    //将pdf文档转换成图片
    $im = new imagick('temp.pdf');
    $im->setImageFormat( "jpg" );
    $img_name = time().'.jpg';
    $im->setSize(800,600);
    $im->writeImage($img_name);
    $im->clear();
    $im->destroy();

這裡使用了HTML2PDF的程式碼,其實個人建議使用tcpdf的,畢竟tcpdf的版本更新,功能更為強大。經過實際測試,tcpdf對中文、html格式等的支援更好,相對而言,HTML2PDF有點慘不忍睹,較長的中文會出現無法自動換行等基本錯誤。

但同時,這種方法存在一個較大的缺陷,當插入了圖片等媒體後,經常會出現一頁內無法放進去需要重新在另外一頁進行排版的問題,從而生成的圖片就會有較大的空白區域;同時每頁的內容如果沒有完全排滿的話,生成的圖片同樣存在較大的空白區域,十分不美觀。

因此,並不推薦這種方式。

3. 透過截圖

該種方式類似於採用瀏覽器的截圖功能,直接將某個URL位址的內容進行截圖。相對前面兩種方式而言:第一,對於富文本的html內容渲染更為方便、簡單,直接產生html程式碼即可;第二,內容排版更為合理,不會出現pdf文件中存在的空白區域等問題;第三,對於中文的支援較為友善。

目前主要的開源專案包括:

khtml2png:基於Linux平台,可以將html轉成圖片格式,有以下要求:

g++
KDE 3.x
kdelibs for KDE 3.x (kdelibs4-dev)
zlib (zlib1g-dev)
cmake

對於伺服器而言,尤其是資源比較吃緊的VPS而言,安裝一個KEDPS有點花銷太大。

CutyCapt及其兄弟版本IECapt:其中CutyCapt是基於Linux、Windows平台,IECapt基於Windows平台,支援svg,ps,pdf,itext,html,rtree,png,jpeg,mng,tiff,gif,bmp,ppm, xbm,xpm等多種格式,使用均較為簡單,直接使用以下指令。

注意:CutyCapt的可執行指令在Windows平台和Linux平台下的大小寫不太一致。

./CutyCapt --url=http://www.php.cn --out=example.png 
IECapt --url=http://www.php.cn/ --out=localfile.png

它的部署要求是:

CutyCapt depends on Qt 4.4.0+.

但是它比khtml2png好的一點是它可以不用裝X server,可以用Xvfb這種輕量級的東西,然後可以這樣使用:

xvfb-run --server-args="-screen 0, 1024x768x24" ./CutyCapt --url=... --out=...

通過對各種對各種對實現方式進行實際的對比,本人傾向於採用CutyCapt的方式。

透過對各種實現方式進行實際的對比,本人傾向於採用CutyCapt的方式。

具体实现过程

1、通过嵌入富文本编辑器,提供富文本编辑功能,同时可以提供对作者信息、版权标记、图片大小格式等的定制。

2、将提交的内容进行过滤,并生成htm/html文档,通过CSS对生成的文档内容进行格式渲染。

3、通过PHP执行CutyCapt命令,对生成的网页文件进行截图。

到这一步已经完全可以实现html内容生成图片的功能了,但CutyCapt生成的图片相对而言会比较大,因此还可以进一步进行优化。

4、通过imagick对生成的图片进行优化

imagick具有强大的图片处理功能,可以优化CutyCapt生成的图片的质量及大小,同时还可以方便地进行加水印等操作。

开发经验分享

在实际开发过程中碰到了各种问题,进行一些分享。

1、操作系统选择

CutyCapt及imagick都有Linux和Windows的版本,在Windows下面的开发、运行不存在较大的问题,按照正常步骤进行安装配置即可。

在Linux平台下,CutyCapt的安装教程可参考http://www.cszhi.com/20130305/cutycapt.html:

centos下安装cutycapt:

(1)安装qt47

增加qt47的源

vim /etc/yum.repos.d/atrpms.repo
//加入如下内容
[atrpms]
name=CentOS $releasever – $basearch – ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/stable
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms
gpgcheck=1
enabled=1
[atrpms-testing]
name=CentOS $releasever – $basearch - ATrpms testing
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/testing
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms
gpgcheck=1
enabled=1
//进行安装
yum update
yum install qt47
yum install qt47-devel
yum install qt47-webkit
yum install qt47-webkit-devel

2、安装cutycapt

yum install svn
svn co https://cutycapt.svn.sourceforge.net/svnroot/cutycapt
mv cutycapt/CutyCapt /usr/local/cutycapt
cd /usr/local/cutycapt
qmake
qmake-qt47

3、安装xvfb

yum install Xvfb

4、测试cutycapt截图

xvfb-run --server-args="-screen 0, 1024x768x24" CutyCapt --url=http://www.php.cn --out=php.png

5、将xvfb置入后台运行

Xvfb -fp /usr/share/fonts :0 -screen 0 1024x768x24 &
DISPLAY=:0 ./CutyCapt --url=http://www.php.cn --out=php.png

ubuntu下安装cutycapt

1、两条命令搞定

apt-get install cutycapt
apt-get install xvfb

2、测试截图

xvfb-run --server-args="-screen 0, 1024x768x24" CutyCapt --url=http://www.php.cn --out=php.png

中文乱码问题:

将windows下的中文字体上传至/usr/share/fonts目录,执行下命令fc-cache即可。

在这里,作者想说的是,尽量选择Ubuntu吧,安装方便;更重要的是,CentOS下面会出现各种问题,如CutyCapt: cannot connect to X server :99等,会让你非常郁闷,我甚至安装了新的包含Gnome、KDE桌面环境的操作系统仍无法解决,而在Ubuntu下面几乎不存在任何问题。

2、Web服务器的选择

因为截图功能涉及到PHP需要执行操作系统的CutyCapt命令,可以通过system()或者exec()函数。

作者分别使用了apache和Nginx两种Web服务器,在Nginx下会出现执行调用CutyCapt的PHP脚本无法运行的情况,会遇到比较麻烦的权限问题,http://alfred-long.iteye.com/blog/1578904中提供了一种解决方案,但作者没有测试成功。使用apache服务器则是一路畅通,不存在这个问题。

因此,作者建议选择Ubuntu+apache的组合,千万不要选择CentOS+Nginx,需要解决的麻烦问题太多,从而也容易造成一些不安全的因素。

安装代码如下:

apt-get install apache2
apt-get install php5 libapache2-mod-php5

3、Ubuntu中安装imagick

apt-get install php5-dev php5-cli php-pear   //安装支持环境
apt-get install imagemagick   //有可能不是最新版本,需要通过源代码安装最新版本
//源代码方式安装http://www.imagemagick.org/script/download.php
cd /usr/local/src 
wget ftp://ftp.kddlabs.co.jp/graphics/ImageMagick/ImageMagick-6.8.7-0.tar.gz
tar xzvf ImageMagick-6.8.7-0.tar.gz
cd ImageMagick-6.8.7-0/
./configure && make && make install
apt-get install graphicsmagick-libmagick-dev-compat
pecl install imagick
echo extension=imagick.so >>/etc/php5/conf.d/imagick.ini
service apache2 restart

常见错误:

在运行pecl install imagick 时有以下出错提示:

checking if ImageMagick version is at least 6.2.4... configure: error: no. You need at least Imagemagick version 6.2.4 to use Imagick. ERROR: `/tmp/pear/temp/imagick/configure --with-imagick=hjw' failed

根据提示是没有安装Imagemagick或者Imagemagick版本不够,可以通过源代码的方式安装最新版本的Imagemagick。

4、Linux平台下的字体渲染

可以将Windows平台下的雅黑、宋体、楷体、黑体等常用中文字体安装到Ubuntu系统中,避免出现截图中的字体不好看的情况,同时也满足对富文本编辑中支持的字体进行渲染。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn