[原文連接]duanruilong.github.io/blog/2018/0…前端
ImageMagick 包括一組命令行工具來操做圖片,以前的ImageMagick實現base64圖片的邏輯在服務器端可能會形成溢出的事故,因此在接下的文章裏會介紹另一種好的實現方式就是----convert命令。使用命令格式的形式去生成圖片和大小的裁剪數據格式的轉換。git
magick:
建立、編輯圖像,轉換圖像格式,以及調整圖像大小、模糊、裁切、除去雜點、抖動 ( dither )、繪圖、翻轉、合併、從新採樣等。github
convert:
等同於 magick 命令。web
identify:
輸出一個或多個圖像文件的格式和特徵信息,如分辨率、大小、尺寸、色彩空間等。bash
mogrify:
與 magick 功能同樣,不過不須要指定輸出文件,自動覆蓋原始圖像文件。服務器
composite:
將一個圖片或多個圖片組合成新圖片。curl
montage:
組合多個獨立的圖像來建立合成圖像。每一個圖像均可以用邊框,透明度等特性進行裝飾。ide
compare:
從數學和視覺角度比較源圖像與重建圖像之間的差別。工具
display:
在任何 X server 上顯示一個圖像或圖像序列。測試
animate:
在任何 X server 上顯示圖像序列。
import:
保存 X server 上的任何可見窗口並把它做爲圖像文件輸出。能夠捕捉單個窗口,整個屏幕或屏幕的任意矩形部分。
conjure:
解釋並執行 MSL ( Magick Scripting Language ) 寫的腳本。
stream:
一個輕量級工具,用於將圖像或部分圖像的一個或多個像素組件流式傳輸到存儲設備。在處理大圖像或原始像素組件時頗有用。
基本命令的使用,遵循 Unix 風格的標準格式,例如 command [options] input_image output_image
將一張寬高 300x300 的圖片 goods.png 轉換成 200x200 的goods.jpg,能夠這樣用
convert -resize 200x200 goods.png goods.jpg
複製代碼
$item_img='https://img.alicdn.com/bao/uploaded/i1/1750208593/TB1rgM3hhtnkeRjSZSgXXXAuXXa_!!0-item_pic.jpg';
$item_title='測試字體';
$shop_title='測試店鋪';
$shop_img='http://q.aiyongbao.com/item/web/images/qap_img/mobile/userAvatar.png';
$qr_img='https://img.alicdn.com/tfscom/TB1uJDStYZnBKNjSZFKwu3GOVXa.png';
$numid_share='0000000';
$qr_title='長按識別二維碼';
// 對寶貝標題裁剪
$drawtitone=mb_substr($item_title,0,13, 'utf-8');
$drawtittow=mb_substr($item_title,13,13, 'utf-8');
$drawtitthree=mb_substr($item_title,26,13, 'utf-8');
$time_date = time(); // 時間戳
$workDir = '/data/tmp/'.$numid_share.'_con'.$time_date; // 目標路徑---->指定一個文件夾保存生成圖片過程裏的圖片
複製代碼
咱們這裏須要一個拼接圖片的連接,因此先下載到以前的建立的文件夾下,由於這些素材圖片只是爲了最後的拼接,最後能夠徹底刪除。
$item_img_down = $workDir.'/itemimage.jpg';
$shop_img_down = $workDir.'/shopimage.jpg';
$qr_img_down = $workDir.'/qrimage.jpg';
// 下載寶貝主圖
\NetworkUtils::curlDownload($item_img, $item_img_down);
// 下載店鋪圖片
\NetworkUtils::curlDownload($shop_img, $shop_img_down);
// 下載二維碼
\NetworkUtils::curlDownload($qr_img, $qr_img_down);
複製代碼
\NetworkUtils::curlDownload($item_img, $item_img_down);
下載$item_img
保存在目標路徑文件夾下的$workDir.'/itemimage.jpg'
路徑。
$fontFamily = '/usr/share/fonts/chinese/msyh.ttf';
$fontColor = '#333333';
$fontColor_shoptitle = '#999999';
$fontColor_qrtitlt = '#666666';
複製代碼
建立一個750x1046
白色的底圖,咱們能夠在上面繪製文字
// 建立一個底圖(而且加上一些文字)
$back_img=$workDir.'/bg.jpg'; //要生成的圖片的路徑---->能夠在服務器端看到
$back_cmds="convert 'xc:[750x1046!]' -background white -font {$fontFamily} -draw 'text 580,994 \"{$qr_title}\"' -fill \"{$fontColor_qrtitlt}\" -pointsize 20 -draw 'text 114,990 \"{$shop_title}\"' -font {$fontFamily} -pointsize 22 -fill '#999999' {$workDir}/bg.jpg";
$result_back_cmds = \SystemCommon::runningCmd($back_cmds);
複製代碼
這裏須要注意一下文字的繪製命令順序,不然會出現沒有生效的問題。
-font {$fontFamily} -draw 'text 580,994 \"{$qr_title}\"' -fill \"{$fontColor_qrtitlt}\" -pointsize 20
解釋一下:
xc:[100x40!]
: 設置畫布大小的一種簡寫方式,方括號裏寫入畫布寬高,注意要加 !-fill 'rgba(0, 0, 0, 0)'
:設置了文本的填充顏色text 114,990
: 對文字進行定位-font
:指定字體-pointsize
:指定文本的字體大小-draw
:繪圖選項,text 聲明繪製文本, 0,0 聲明文本距離圖片左上角的偏移值,繪製文本的格式爲 text x,y string,固然還能夠繪製其餘類型,諸如圓 ( circle )、折線 ( polyline )繼續添加文字:
$back_img_shoptitle=$workDir.'/btitle.jpg'; //要生成的圖片的路徑
$back_cmds_shoptitle="convert -draw 'text 40,820 \"{$drawtitone}\"' -font {$fontFamily} -pointsize 32 -fill \"{$fontColor}\" -draw 'text 40,866 \"{$drawtittow}\"' -font {$fontFamily} -pointsize 32 -fill \"{$fontColor}\" -draw 'text 40,912 \"{$drawtitthree}\"' -font {$fontFamily} -pointsize 32 -fill \"{$fontColor}\" {$back_img} {$workDir}/btitle.jpg";
$result_back_cmds_shoptitle = \SystemCommon::runningCmd($back_cmds_shoptitle);
複製代碼
效果: (白色的背景可能顯示不是很好)
如今就能夠在以前獲得的圖片上拼接所須要的圖片了
// 在底圖上合併商品主圖
$back_img_itemimg='/data/tmp/' . md5(microtime(true)).'.jpg'; //要生成的圖片的路徑
$geometryX = "+" . 0; // 定位
$geometryY = "+" . 0; // 定位
$customPicPos = "northwest";
$back_cmds_itemimg = "convert {$back_img_shoptitle} {$workDir}/item_img_mag.jpg -gravity {$customPicPos} -geometry {$geometryX}{$geometryY} -compose over -composite -antialias -set colorspace sRGB -colorspace sRGB {$workDir}/result.jpg";
$result_back_cmds_itemimg = \SystemCommon::runningCmd($back_cmds_itemimg);
複製代碼
解釋一下:
-geometry
: 設置文本在圖片裏的排列方式 ( 相似 CSS 裏的 align-items + justify-content ),center 表示水平垂直都居中,其餘值還能夠是:NorthWest, North, NorthEast, West, East, SouthWest, South, SouthEast,不記大小寫composite
: 將一個圖片或多個圖片組合成新圖片。這裏是把{$workDir}/item_img_mag.jpg
路徑的圖片繪製到以前繪製文字的圖片上$back_img_shoptitle
,最終獲得的圖片保存路徑是在{$workDir}/result.jpg
讓咱們繼續操做圖片
// 合併二維碼
$geometryXshop = "+" . 40;
$geometryYshop = "+" . 950;
$back_cmds_shopimg = "convert {$workDir}/result.jpg {$workDir}/shop_img_mag.jpg -gravity {$customPicPos} -geometry {$geometryXshop}{$geometryYshop} -compose over -composite -antialias -set colorspace sRGB -colorspace sRGB {$workDir}/result1.jpg";
$result_back_cmds_shopimg = \SystemCommon::runningCmd($back_cmds_shopimg);
// 合併店鋪圖標
$geometryXqr = "+" . 520;
$geometryYqr = "+" . 784;
$back_cmds_qrimg = "convert {$workDir}/result1.jpg {$workDir}/qr_img_mag.jpg -gravity {$customPicPos} -geometry {$geometryXqr}{$geometryYqr} -compose over -composite -antialias -set colorspace sRGB -colorspace sRGB {$workDir}/result2.jpg";
$result_back_cmds_qrimg = \SystemCommon::runningCmd($back_cmds_qrimg);
複製代碼
效果:
發現圖片並非咱們預期的效果,拼接咱們也設置了圖片的大小,可是沒有起做用,嘗試過不一樣的方案後決定在拼接以前把圖片統一放大爲須要拼接的尺寸來操做。
須要對多拼接的圖片都進行操做
// 看來須要先放大主圖
$item_img_m="convert -resize '750x766!' {$item_img_down} {$workDir}/item_img_mag.jpg";
$item_img_mag = \SystemCommon::runningCmd($item_img_m);
// 看來須要先放大二維碼
$shop_img_m="convert -resize 64x64 {$shop_img_down} {$workDir}/shop_img_mag.jpg";
$shop_img_mag = \SystemCommon::runningCmd($shop_img_m);
// 看來須要先放大店鋪圖標
$qr_img_m="convert -resize 200x200 {$qr_img_down} {$workDir}/qr_img_mag.jpg";
$qr_img_mag = \SystemCommon::runningCmd($qr_img_m);
複製代碼
-resize 延伸解讀
IamgeMagick 提供了幾種符號來定義縮放
convert -resize '150x100!' goods.jpg thumbnail.jpg
convert -resize '150x100>' goods.jpg thumbnail.jpg
convert -resize '150x100<' goods.jpg thumbnail.jpg
複製代碼
!
:無論圖片寬高如何,都縮放成 150x100 這樣的尺寸。>
:只有寬高均大於 150x100 的圖片才縮放成該尺寸 ( 按比例取最大值 ),小於的圖片不作處理。<
:與 > 功能相反縮放對比
這樣的結果也不是咱們須要的
只有convert -resize '750x766!' {$item_img_down} {$workDir}/item_img_mag.jpg
這樣固定尺寸以後能夠獲得:
咱們最後一樣的以base64格式輸出給前端
$stdout = trim($result_back_cmds_qrimg["stdout"]);
$Return = array();
if (empty($stdout) || strpos($result_back_cmds_qrimg["stderr"], "identify") != false) { // runningCmd執行成功
$dest_img = $workDir.'/result2.jpg';
// /*圖片轉換爲 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['dest_img']=$dest_img;
$Return['type']='success';
$Return['msg']=1;
return $Return;
}
$Return['data']='';
$Return['msg']=2;
return $Return;
複製代碼
$workDir.'/result2.jpg
是咱們最終的拼接圖片,至於文件夾下的其餘圖片,能夠選擇刪除。咱們只要獲得結果就行了。
(小姐姐拼接圖)
此次convert命令
的介紹是以解讀整個方法的形式,對拼接的開始進行到結尾生成最終的圖片,但願對你們有力所能及的幫助。
歡迎光顧我的博客Blog