在PHP裏使用 ImageMagick 生成 base64 圖片

我的博客 duanruilong.github.io/blog/前端

本文原地址duanruilong.github.io/blog/2018/0…git

最近的PHP項目中,須要用到畫圖和圖片拼接效果,這裏是一些開發過程裏用到的一些點還有就是一些踩過的坑。經過ImageMagick生成base64圖片格式,爲前端所使用。 github

PHP
PHP

一些須要的知識點數組

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個字符的數組:bash

['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類進行圖像的操做ui

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:經過傳入一個通道常量,來開啓通道模式。爲了支持多個通道,能夠經過二進制運算的操做來合併多個通道常量。

到這裏就能夠獲得一個合併的圖片了
一、加一個header信息,能夠直接在網頁上查看圖片
    header("Content-Type: img/png");
    echo $img;
二、能夠把圖片在指定目錄中生成,在指定目錄下生成爲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).圖片上拼接文字

寫入文字以添加店鋪文字爲例,逐步完成文字的寫入。spa

$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);  // 畫在地板上
複製代碼

詳細解讀:

  • 一、實例化ImagickDraw類: $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);

寫入文字這個地方的一些坑:

沒有設置字體格式時,中文字會解析錯誤 (英文沒有問題)

PHP

(漢字解析失敗)

PHP

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

PHP

(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'回車字符,須要特殊處理才能夠正確顯示圖片。

PHP

(最後獲得的合併圖片)

PHP

(調整拼接圖片大小獲得不一樣的圖片)

PHP

最後來一組單打詹!!!

以爲喜歡歡迎關注,start

相關文章
相關標籤/搜索