在PHP裡使用ImageMagick生成base64圖片
個人部落格 duanruilong.github.io/blog/
本文原地址 PHP%25E9%2587%258C%25E5%25BE%2588%25E5%25A5%25BD%25E7%259A%2584%25E4%25BD%25BF%25E7%2594%25A8ImageMagick%2F" rel="nofollow,noindex">duanruilong.github.io/blog/2018/0…
最近的PHP專案中,需要用到畫圖和圖片拼接效果,這裡是一些開發過程裡用到的一些點還有就是一些踩過的坑。通過ImageMagick生成base64圖片格式,為前端所使用。


一些需要的知識點
PHP將圖片轉base64編碼以及base64圖片轉換為圖片並儲存程式碼
圖片轉base64編碼
/*圖片轉換為 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圖片轉換為圖片並儲存
/*base64格式編碼轉換為圖片並儲存對應資料夾 */ 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)){ //檢查是否有該資料夾,如果沒有就建立,並給予最高許可權 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個字元來表示任意二進位制資料的方法。 Base64的原理很簡單,首先,準備一個包含64個字元的陣列:
['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']
然後,對二進位制資料進行處理,每3個位元組一組,一共是3x8=24bit,劃為4組,每組正好6個bit
如果要編碼的二進位制資料不是3的倍數,最後會剩下1個或2個位元組怎麼辦?Base64用\x00位元組在末尾補足後,再在編碼的末尾加上1個或2個=號,表示補了多少位元組,解碼的時候,會自動去掉。
使用jpg圖片體積要比png小 使用PHP的Imagick類進行影象的操作
Imagick具體操作
(1).建立一個底圖,寬750px,高1046px,白色背景,格式為jpg的圖片
// 初始化一個畫板 $img =new Imagick(); $img->newImage(750,1046,'white','jpg') ; 複製程式碼
(2).在底圖上新增需求圖片
前提是我們已經知道了需要合併的圖片連結地址
$item_img='https://img.alicdn.com/bao/uploaded/i1/1750208593/TB1rgM3hhtnkeRjSZSgXXXAuXXa_!!0-item_pic.jpg' 第一步:例項化圖片 $imgtwo = new Imagick($item_img); 第二步:設定新增圖片的大小 $imgtwo->resizeImage(750,764,Imagick::FILTER_LANCZOS,1); 關於resizeImage引數說明 bool Imagick::resizeImage ( int $columns , int $rows , int $filter , float $blur [, bool $bestfit = false ] ) 引數: ● columns 圖片的寬度 ● rows 圖片高度 ● filter 過濾器,用於過濾圖片,有高斯filte根據情況而定 ● 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 ] ) 引數: ● composite_object :用於合併的圖片的Imagick物件 ● composite:合併操作,定義操作常量。 具體請檢視 合併操作常量列表 ● x:相對影象頂點左上位置(0,0)的橫座標 ● y:相對影象頂點左上位置(0,0)的縱座標 ● channel:通過傳入一個通道常量,來開啟通道模式。為了支援多個通道,可以通過二進位制運算的操作來合併多個通道常量。 到這裡就可以得到一個合併的圖片了 1、加一個header資訊,可以直接在網頁上檢視圖片 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;//要生成的圖片的路徑,隨機生成圖片名稱 複製程式碼
(3).圖片上拼接文字
寫入文字以新增店鋪文字為例,逐步完成文字的寫入。
$shop_title='測試店鋪'; // 新增店鋪文字 $drawQr = new ImagickDraw(); // 例項化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);// 畫在地板上 複製程式碼
詳細解讀:
$drawQr = new ImagickDraw(); $drawQr -> setFillColor(new ImagickPixel('#999999')); $drawQr -> setFontSize('24'); $drawQr -> setFont('../../conf/Microsoftyahei.ttf'); $draw->setTextAlignment(Imagick::ALIGN_RIGHT);
ps: Imagick::ALIGN_RIGHT 朝右邊 Imagick::ALIGN_LEFT 左邊 Imagick::ALIGN_CENTER 中間
$drawQr -> setTextEncoding("utf-8"); $drawQr -> annotation(114,990,$shop_title); $img -> drawImage($drawQr);
寫入文字這個地方的一些坑:
沒有設定字型格式時,中文字會解析錯誤 (英文沒有問題)

(漢字解析失敗)

(設定字型格式正常顯示)

(4).圖片base64匯出
最終得到的圖片我們組要以base64的格式傳遞給前端,進行以下操作,把我們最後拼接的到的圖片base64轉換輸出。
$dest_img='/data/tmp/' . md5(microtime(true)).'.'.$type; //要生成的圖片的路徑 $Return = array(); // *圖片轉換為 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資料裡包含有 '\r\n'
回車字元,需要特殊處理才可以正確顯示圖片。

(最後得到的合併圖片)

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

最後來一組單打詹!!!
覺得喜歡歡迎關注,start