> 個(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