PHP里使用ImageMagick生成base64圖片

> 個(gè)人博客 [https://duanruilong.github.io/blog/](https://duanruilong.github.io/blog/)

> 本文原地址[https://duanruilong.github.io/blog/2018/09/05/%E5%9C%A8PHP%E9%87%8C%E5%BE%88%E5%A5%BD%E7%9A%84%E4%BD%BF%E7%94%A8ImageMagick/](https://duanruilong.github.io/blog/2018/09/05/%E5%9C%A8PHP%E9%87%8C%E5%BE%88%E5%A5%BD%E7%9A%84%E4%BD%BF%E7%94%A8ImageMagick/)

最近的PHP項(xiàng)目中誊垢,需要用到畫圖和圖片拼接效果,這里是一些開發(fā)過程里用到的一些點(diǎn)還有就是一些踩過的坑症见。通過ImageMagick生成base64圖片格式喂走,為前端所使用。

![PHP](http://upload-images.jianshu.io/upload_images/5412276-e805ee8d1d678a68?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![PHP](http://upload-images.jianshu.io/upload_images/5412276-5940a11639adde0c?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

> 一些需要的知識(shí)點(diǎn)

# PHP將圖片轉(zhuǎn)base64編碼以及base64圖片轉(zhuǎn)換為圖片并保存代碼

## 圖片轉(zhuǎn)base64編碼

```

/*圖片轉(zhuǎn)換為 base64格式編碼*/

$img = 'uploads/about.png';

$base64_img = base64EncodeImage($img);

echo '<img src="' . $base64_img . '" />';

function base64EncodeImage ($image_file) {

? ? $base64_image = '';

? ? $image_info = getimagesize($image_file);

? ? $image_data = fread(fopen($image_file, 'r'), filesize($image_file));

? ? $base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));

? ? return $base64_image;

}

```

## base64圖片轉(zhuǎn)換為圖片并保存

```

/*? base64格式編碼轉(zhuǎn)換為圖片并保存對(duì)應(yīng)文件夾 */

function base64_image_content($base64_image_content,$path){

? ? //匹配出圖片的格式

? ? if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){

? ? ? ? $type = $result[2];

? ? ? ? $new_file = $path."/".date('Ymd',time())."/";

? ? ? ? if(!file_exists($new_file)){

? ? ? ? ? ? //檢查是否有該文件夾谋作,如果沒有就創(chuàng)建芋肠,并給予最高權(quán)限

? ? ? ? ? ? mkdir($new_file, 0700);

? ? ? ? }

? ? ? ? $new_file = $new_file.time().".{$type}";

? ? ? ? if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){

? ? ? ? ? ? return '/'.$new_file;

? ? ? ? }else{

? ? ? ? ? ? return false;

? ? ? ? }

? ? }else{

? ? ? ? return false;

? ? }

}

echo base64_image_content($base64_img,"uploads/");

```

# base64

Base64是一種用64個(gè)字符來表示任意二進(jìn)制數(shù)據(jù)的方法。

Base64的原理很簡單遵蚜,首先座哩,準(zhǔn)備一個(gè)包含64個(gè)字符的數(shù)組:

`['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']`

然后蹋肮,對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行處理雷激,每3個(gè)字節(jié)一組,一共是3x8=24bit肴甸,劃為4組,每組正好6個(gè)bit

如果要編碼的二進(jìn)制數(shù)據(jù)不是3的倍數(shù)囚巴,最后會(huì)剩下1個(gè)或2個(gè)字節(jié)怎么辦原在?Base64用\x00字節(jié)在末尾補(bǔ)足后,再在編碼的末尾加上1個(gè)或2個(gè)=號(hào)彤叉,表示補(bǔ)了多少字節(jié)庶柿,解碼的時(shí)候,會(huì)自動(dòng)去掉秽浇。

使用jpg圖片體積要比png小

使用PHP的Imagick類進(jìn)行圖像的操作

# Imagick具體操作

## (1).創(chuàng)建一個(gè)底圖,寬750px浮庐,高1046px,白色背景柬焕,格式為jpg的圖片

```

// 初始化一個(gè)畫板

? ? ? ? $img =new Imagick();

? ? ? ? $img->newImage(750,1046,'white','jpg') ;


```

## (2).在底圖上添加需求圖片

前提是我們已經(jīng)知道了需要合并的圖片鏈接地址

```

$item_img='https://img.alicdn.com/bao/uploaded/i1/1750208593/TB1rgM3hhtnkeRjSZSgXXXAuXXa_!!0-item_pic.jpg'

第一步:實(shí)例化圖片

$imgtwo = new Imagick($item_img);

第二步:設(shè)置添加圖片的大小

$imgtwo->resizeImage(750,764,Imagick::FILTER_LANCZOS,1);

關(guān)于resizeImage參數(shù)說明

? ? bool Imagick::resizeImage ( int $columns , int $rows , int $filter , float $blur [, bool $bestfit = false ] )

參數(shù):

? ● columns 圖片的寬度

? ● rows 圖片高度

? ● filter 過濾器兔辅,用于過濾圖片,有高斯filte根據(jù)情況而定

? ● blur blur=1 為虛化击喂, blur =-1 為銳化

第三步:與底圖合并

$img->compositeImage($imgtwo,$imgtwo->getImageCompose(),0,0);

使用compositeImage();

? ? bool Imagick::compositeImage ( Imagick $composite_object , int $composite , int $x , int $y [, int $channel = Imagick::CHANNEL_ALL ] )

參數(shù):

? ● composite_object :用于合并的圖片的Imagick對(duì)象

? ● composite:合并操作维苔,定義操作常量。 具體請(qǐng)查看 合并操作常量列表

? ● x:相對(duì)圖像頂點(diǎn)左上位置(0,0)的橫坐標(biāo)

? ● y:相對(duì)圖像頂點(diǎn)左上位置(0,0)的縱坐標(biāo)

? ● channel:通過傳入一個(gè)通道常量懂昂,來開啟通道模式介时。為了支持多個(gè)通道,可以通過二進(jìn)制運(yùn)算的操作來合并多個(gè)通道常量凌彬。

到這里就可以得到一個(gè)合并的圖片了

1沸柔、加一個(gè)header信息,可以直接在網(wǎng)頁上查看圖片

? ? header("Content-Type: img/png");

? ? echo $img;

2铲敛、可以把圖片在指定目錄中生成褐澎,在指定目錄下生成為img.png

$file="./img.png";

$img->writeImage($file);

我這里是這樣處理:

? ? header ( 'Content-type: ' . strtolower ($img->getImageFormat ()) );

? ? $type = strtolower($img->getImageFormat());

? ? $dest_img='/data/tmp/' . md5(microtime(true)).'.'.$type;? ? //要生成的圖片的路徑,隨機(jī)生成圖片名稱

```

## (3).圖片上拼接文字

寫入文字以添加店鋪文字為例伐蒋,逐步完成文字的寫入工三。

```

? ? $shop_title='測(cè)試店鋪';

? ? // 添加店鋪文字

? ? $drawQr = new ImagickDraw(); // 實(shí)例化ImagickDraw

? ? $drawQr -> setFillColor(new ImagickPixel('#999999')); // 顏色

? ? $drawQr -> setFontSize('24'); // 大小

? ? $drawQr -> setFont('../../conf/Microsoftyahei.ttf'); // 字體

? ? $drawQr -> setTextAlignment(Imagick::ALIGN_LEFT); // 字體方向

? ? // ps: Imagick::ALIGN_RIGHT 朝右邊? ? Imagick::ALIGN_LEFT 左邊? Imagick::ALIGN_CENTER 中間

? ? $drawQr -> setTextEncoding("utf-8"); // 字體編碼

? ? $drawQr -> annotation(114,990,$shop_title); // 畫出文字

? ? $img -> drawImage($drawQr);? // 畫在地板上

```

詳細(xì)解讀:

- 1先鱼、實(shí)例化ImagickDraw類:

? ? `$drawQr = new ImagickDraw(); `

- 2俭正、設(shè)置字體顏色

`$drawQr -> setFillColor(new ImagickPixel('#999999')); `

- 3、設(shè)置字體大小

`$drawQr -> setFontSize('24'); `

- 4焙畔、設(shè)置字體格式

`$drawQr -> setFont('../../conf/Microsoftyahei.ttf');`

- 5掸读、設(shè)置字體方向

`$draw->setTextAlignment(Imagick::ALIGN_RIGHT);`

> ps: Imagick::ALIGN_RIGHT 朝右邊? ? Imagick::ALIGN_LEFT 左邊? Imagick::ALIGN_CENTER 中間

- 6、設(shè)置字體編碼

`$drawQr -> setTextEncoding("utf-8");`

- 7、畫出文字

`$drawQr -> annotation(114,990,$shop_title); `

- 8儿惫、在底圖上寫入字體

`$img -> drawImage($drawQr);`

寫入文字這個(gè)地方的一些坑:

沒有設(shè)置字體格式時(shí)澡罚,中文字會(huì)解析錯(cuò)誤

(英文沒有問題)

![PHP](http://upload-images.jianshu.io/upload_images/5412276-1ebdd91dd08d6bf4?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

(漢字解析失敗)

![PHP](http://upload-images.jianshu.io/upload_images/5412276-8a18eb586fa58887?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

(設(shè)置字體格式正常顯示)

![PHP](http://upload-images.jianshu.io/upload_images/5412276-d4a5388ce3e36fdb?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## (4).圖片base64導(dǎo)出

最終得到的圖片我們組要以base64的格式傳遞給前端肾请,進(jìn)行以下操作始苇,把我們最后拼接的到的圖片base64轉(zhuǎn)換輸出。

```

? ? $dest_img='/data/tmp/' . md5(microtime(true)).'.'.$type; //要生成的圖片的路徑

? ? $Return = array();

? ? // *圖片轉(zhuǎn)換為 base64格式編碼*

? ? $base64_image = '';

? ? $image_info = getimagesize($dest_img);

? ? $image_data = fread(fopen($dest_img, 'r'), filesize($dest_img));

? ? $base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));

? ? $Return['data']=$base64_image;

? ? return? $Return;

```

`$base64_image`就是base64格式的圖片筐喳。

需要注意的是前端得到的額base64數(shù)據(jù)里包含有`'\r\n'`回車字符催式,需要特殊處理才可以正確顯示圖片。

![PHP](http://upload-images.jianshu.io/upload_images/5412276-1901352482215ddf?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

(最后得到的合并圖片)

![PHP](http://upload-images.jianshu.io/upload_images/5412276-eaefa07403444432?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

(調(diào)整拼接圖片大小得到不同的圖片)

![PHP](http://upload-images.jianshu.io/upload_images/5412276-6d349e6b5d242161?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

最后來一組單打詹1芄椤H僭隆!

覺得喜歡歡迎關(guān)注梳毙,start

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哺窄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子账锹,更是在濱河造成了極大的恐慌萌业,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奸柬,死亡現(xiàn)場(chǎng)離奇詭異生年,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)廓奕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門抱婉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人桌粉,你說我怎么就攤上這事蒸绩。” “怎么了铃肯?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵患亿,是天一觀的道長。 經(jīng)常有香客問我押逼,道長步藕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任宴胧,我火速辦了婚禮漱抓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恕齐。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布显歧。 她就那樣靜靜地躺著仪或,像睡著了一般。 火紅的嫁衣襯著肌膚如雪士骤。 梳的紋絲不亂的頭發(fā)上范删,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音拷肌,去河邊找鬼到旦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛巨缘,可吹牛的內(nèi)容都是我干的添忘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼若锁,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼搁骑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起又固,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤仲器,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后仰冠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乏冀,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年洋只,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了煤辨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡木张,死狀恐怖众辨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舷礼,我是刑警寧澤鹃彻,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站妻献,受9級(jí)特大地震影響蛛株,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜育拨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一谨履、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧熬丧,春花似錦笋粟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绿淋。三九已至,卻和暖如春尝盼,著一層夾襖步出監(jiān)牢的瞬間吞滞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工盾沫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裁赠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓赴精,卻偏偏與公主長得像佩捞,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子祖娘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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