【工具】PHP實現微信頭像加國旗(分享圖片合成方法)

環境準備

win10+php7+GD擴展,windows系統安裝擴展可以直接把php.ini文件中以下語句前的;去掉:

extension=gd2

國旗文件(昨天拿ipad摳了一天沒摳下,所以這是截的別人頭像上的圖qaq:

國旗文件(昨天拿pad摳了一天沒摳下,所以這是截的別人頭像上的圖qaq)頭像文件:
頭像

合成方法

<?php
/**
 *
 *
 * User: 原子醬
 * Date: 2019/9/24
 * Time: 16:27
 */

$flagFile = '../img/flag.png'; // 國旗文件
$posterImgPath = '../img/header.jpg'; // 頭像

merge($posterImgPath, $flagFile);

function merge($posterImgPath, $tmpFile){
    // 頭像與國旗,我們給它限制一下大小
    $image1 = CreatePoster::CreateImage($posterImgPath, 960, 960);
    $image2 = CreatePoster::CreateImage($tmpFile, 320, 320, 600, 600);

    // 設置自定義-指定寬度來計算點位
    $config = [
        'dst_x' => 640,
        'dst_y' => 640,
        'src_x' => 0,
        'src_y' => 0,
        'src_w' => 320,
        'src_h' => 320,
        'pct'   => 100,
    ];

    // 合成海報底圖跟二維碼
    CreatePoster::ImagesMerge($image1, $image2, $config);
    CreatePoster::look($image1); // 瀏覽圖片
}

其中CreatePoster類如下:

/**
 *  生成海報圖
 * @author daichongweb
 * @url daichongweb.cn,daichongweb.com
 */
class CreatePoster
{
    public static function start()
    {
        echo('<h2>歡迎使用:)</h2>');
        echo '<hr />';
        echo '海報圖製作步驟:';
        echo '<br />';
        echo '<br />';
        echo '&emsp;&emsp;1.創建畫板(普通畫板用CreatePalette;圖像畫板用CreateImage)';
        echo '<br />';
        echo '&emsp;&emsp;2.合併圖片(ImagesMerge)';
        echo '<br />';
        echo '&emsp;&emsp;3.插入文字(CreateChars)';
        echo '<br />';
        echo '&emsp;&emsp;4.插入劃線(CreateLine)';
        echo '<br />';
        echo '&emsp;&emsp;5.下載或查看';
        echo '<br />';
        echo('<h2>注意事項:</h2>');
        echo '<hr />';
        echo "<font color='red'>注意事項:主圖儘量改爲png格式,這樣的話圖片會很清晰,在瀏覽器中直接查看效果不是很好,下載下來就會很清晰的。</font>";
    }

    /**
     * [CreatePalette 新建一個畫板]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    array $config 數據配置
     * @param    int $x_size 畫板的寬度
     * @param    int $y_size 畫板的高度
     * @param    int $red 紅色
     * @param    int $green 綠色
     * @param    int $blue 藍色
     */
    public static function CreatePalette($config)
    {
        $Palette = imagecreate($config['x_size'], $config['y_size']);
        imagecolorallocate($Palette, $config['red'], $config['green'], $config['blue']);
        return $Palette;
    }

    /**
     * [OrthogonBr 畫一個矩形邊框]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $mainBg 畫布資源
     * @param    array $config 數據配置
     * @param    int $x1 x座標
     * @param    int $y1 y座標
     *
     * @param    int $red 紅色
     * @param    int $green 綠色
     * @param    int $blue 藍色
     */
    public static function OrthogonBr($mainBg, $config)
    {
        $color = imagecolorallocate($mainBg, $config['red'], $config['green'], $config['blue']);
        imagerectangle($mainBg, $config['x1'], $config['y1'], $config['x2'], $config['y2'], $color);
    }

    /**
     * [OrthogonBg 畫一個矩形實體]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $mainBg 畫布資源
     * @param    array $config 數據配置
     * @param    int $x1 x座標
     * @param    int $y1 y座標
     *
     * @param    int $red 紅色
     * @param    int $green 綠色
     * @param    int $blue 藍色
     */
    public static function OrthogonBg($mainBg, $config)
    {
        $color = imagecolorallocate($mainBg, $config['red'], $config['green'], $config['blue']);
        imagefilledrectangle($mainBg, $config['x1'], $config['y1'], $config['x2'], $config['y2'], $color);
    }

    /**
     * [CircleBr 畫一個橢圓邊框]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $mainBg 畫布資源
     * @param    array $config 數據配置
     * @param    int $left 距離左邊的距離
     * @param    int $top 距離上邊的距離
     * @param    int $width 寬度
     * @param    int $height 高度
     * @param    int $red 紅色
     * @param    int $green 綠色
     * @param    int $blue 藍色
     */
    public static function CircleBr($mainBg, $config)
    {
        $color = imagecolorallocate($mainBg, $config['red'], $config['green'], $config['blue']);
        imageellipse($mainBg, $config['left'], $config['top'], $config['width'], $config['height'], $color);
    }

    /**
     * [CircleBg 畫一個實體橢圓]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $mainBg 畫布資源
     * @param    array $config 數據配置
     * @param    int $left 距離左邊的距離
     * @param    int $top 距離上邊的距離
     * @param    int $width 寬度
     * @param    int $red 紅色
     * @param    int $green 綠色
     * @param    int $blue 藍色
     */
    public static function CircleBg($mainBg, $config)
    {
        $color = imagecolorallocate($mainBg, $config['red'], $config['green'], $config['blue']);
        imagefilledellipse($mainBg, $config['left'], $config['top'], $config['width'], $config['height'], $color);
    }

    /**
     * [StarBr 畫一個五角星邊框]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $mainBg 畫布資源
     * @param    array $config 數據配置
     * @param    int $r 半徑
     * @param    int $left 距離左邊的距離
     * @param    int $top 距離上邊的距離
     */
    public static function StarBr($mainBg, $config)
    {
        $r = $config['r'];
        $degree36 = deg2rad(36);
        $l = 2 * $r * sin($degree36);
        $a = $l * cos($degree36);
        $b = $l * sin($degree36);
        $c = $l / 2;
        $d = $r * cos($degree36);

        $px1 = $config['left'];
        $py1 = $config['top'];

        $px2 = $px1 + $a;
        $py2 = $py1 + $b;
        $px3 = $px1 + $c;
        $py3 = $py1 + $r + $d;
        $px4 = $px1 - $c;
        $py4 = $py1 + $r + $d;
        $px5 = $px1 - $a;
        $py5 = $py1 + $b;

        $color = imagecolorallocate($mainBg, $config['red'], $config['green'], $config['blue']);

        imageline($mainBg, $px2, $py2, $px5, $py5, $color);
        imageline($mainBg, $px1, $py1, $px3, $py3, $color);
        imageline($mainBg, $px1, $py1, $px4, $py4, $color);
        imageline($mainBg, $px2, $py2, $px4, $py4, $color);
        imageline($mainBg, $px3, $py3, $px5, $py5, $color);
    }

    /**
     * [CreateImage 新建一個圖像畫板]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    url $palette 圖像的地址
     * @param    string $dst_w 目標圖片的寬度
     * @param    string $dst_h 目標圖片的高度
     * @param    string $bgWidth 畫板的寬度
     * @param    string $bgHeight 畫板的高度    這兩項決定了圖片如果小了是否會被拉伸
     */
    public static function CreateImage($palette, $dst_w = '', $dst_h = '', $bgWidth = '', $bgHeight = '')
    {

        $info = getimagesize($palette);

        $backgroundFun = 'imagecreatefrom' . image_type_to_extension($info[2], false);
        $background = $backgroundFun($palette);

        $backgroundWidth = imagesx($background);
        $backgroundHeight = imagesy($background);

        $imageRes = imageCreatetruecolor($bgWidth ? $bgWidth : $backgroundWidth, $bgHeight ? $bgHeight : $backgroundHeight);
        $color = imagecolorallocate($imageRes, 255, 255, 255);
        // 正式使用 這個定要註釋
        // imagecolortransparent($imageRes, $color);
        imagefill($imageRes, 0, 0, $color);

        imagecopyresized($imageRes, $background, 0, 0, 0, 0, $dst_w ? $dst_w : imagesx($background), $dst_h ? $dst_h : imagesy($background), imagesx($background), imagesy($background));

        return $imageRes;
    }

    /**
     * [CreateChars 在畫板中插入文字]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $image 圖片源
     * @param    array $config 配置信息
     * @param    int $red 紅色
     * @param    int $green 綠色
     * @param    int $blue 藍色
     * @param    int $num 次數越多文字越粗
     * @param    int $size 文字大小
     * @param    int $angle 旋轉的角度 默認不旋轉爲0
     * @param    int $x 文字的座標x
     * @param    int $y 文字的座標y
     * @param    int $font 字體文件 這裏一般爲絕對路徑
     * @param    int $text 文字內容
     *
     */
    public static function CreateChars($image, $config)
    {
        //設置文字顏色
        $color = imagecolorexactalpha($image, $config['red'], $config['green'], $config['blue'], $config['alpha']);
        //循環多次爲了加粗字體
        for ($i = 1; $i <= $config['num']; $i++) {

            imagettftext($image, $config['size'], $config['angle'], $config['x'], $config['y'], $color, $config['font'], $config['text']);
        }
        return $image;
    }


    /**
     * add by yuanxiu
     * 文字居中:https://blog.csdn.net/qq409451388/article/details/81238984
     * 水平居中取x的值,高度取藍湖值
     * @param $fontSize
     * @param $font
     * @param $text
     * @param $width
     * @param int $angle
     * @return array
     */
    public static function CenterChars($fontSize, $font, $text, $width, $angle = 0)
    {
        // 水平居中
        $box = imagettfbbox($fontSize, $angle, $font, $text);   //得到字符串虛擬方框四個點的座標
        $len = $box[2] - $box[0];
        $x = ($width - $len)/2;
        $y = $box[3] - $box[5];

        return [
            'x' => $x,
            'y' => $y,
        ];
    }


    /**
     * [CreateLine 畫一條實線]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $image 圖片源
     * @param    array $config 數據配置
     * @param    int $red 紅色
     * @param    int $green 綠色
     * @param    int $blue 藍色
     * @param    int $alpha 透明度 0不透明
     * @param    int $x1 x2      座標x
     * @param    int $y1 y2      座標y
     */
    public static function CreateLine($image, $config)
    {
        //設置線條顏色
        $color = imagecolorexactalpha($image, $config['red'], $config['green'], $config['blue'], $config['alpha']);
        //劃線
        imageline($image, $config['x1'], $config['y1'], $config['x2'], $config['y2'], $color);
        return $image;
    }

    /**
     * [functionName 圖片合併]
     * @author DaiChong
     * @DateTime 2019-05-23
     * 將 src_im 圖像中座標從 src_x,src_y 開始,寬度爲 src_w,高度爲 src_h 的一部分拷貝到 dst_im 圖像中座標爲 dst_x 和 dst_y 的位置上。兩圖像將根據 pct
     * 來決定合併程度,其值範圍從 0 到 100。當 pct = 0 時,實際上什麼也沒做,當爲 100 時對於調色板圖像本函數和 imagecopy() 完全一樣,它對真彩色圖像實現了 alpha *
     * 透明。
     * @return
     */
    public static function ImagesMerge($mainBg, $second, $config)
    {
        imagecopymerge($mainBg, $second, $config['dst_x'], $config['dst_y'], $config['src_x'], $config['src_y'], $config['src_w'], $config['src_h'], $config['pct']);
    }

    /**
     * [AutoWrap 文字換行]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    int $fontsize 字體大小
     * @param    int $angle 角度大小
     * @param    int $fontface 字體文件
     * @param    string $string 文字內容
     * @param    width $width 最大寬度 也就是達到這個寬度之後會換行
     */
    public static function AutoWrap($fontsize, $angle, $fontface, $string, $width)
    {

        $content = "";
        // 將字符串拆分成一個個單字 保存到數組 letter 中
        for ($i = 0; $i < mb_strlen($string); $i++) {
            $letter[] = mb_substr($string, $i, 1);
        }

        foreach ($letter as $l) {
            $teststr = $content . "" . $l;
            $testbox = imagettfbbox($fontsize, $angle, $fontface, $teststr);
            // 判斷拼接後的字符串是否超過預設的寬度
            if (($testbox[2] > $width) && ($content !== "")) {
                $content .= "\n";
            }
            $content .= $l;
        }

        $content = mb_convert_encoding($content, "html-entities", "utf-8");

        return $content;
    }

    /**
     * [look 在瀏覽器中顯示圖片]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $imageRes 圖片源
     * @return
     */
    public static function look($imageRes)
    {
        header("Content-type:image/png");
        imagejpeg($imageRes);
        imagedestroy($imageRes);
    }

    /**
     * [load 下載圖片]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    resource $img 圖片源
     * @param    url $name 主圖地址
     * @param    url $path 下載地址
     * @return
     */
    public static function load($img, $name, $path = './')
    {

        $info = self::getInfo($name);

        $ext = pathinfo($name, PATHINFO_EXTENSION);
        $file_path = $path . date('Y-m-d');

        if (!file_exists($file_path)) {
            mkdir($file_path, 0777, true);
        }

        $rand_name = $file_path . '/' . md5(mt_rand() . time()) . "." . $ext;

        switch ($ext) {
            case 'jpg':
            case 'jpeg':
            case 'jpe':
                imagejpeg($img, $rand_name);
                break;
            case 'png':
                imagepng($img, $rand_name);
                break;
            case 'gif':
                imagegif($img, $rand_name);
                break;
            case 'bmp':
            case 'wbmp':
                imagewbmp($img, $rand_name);
                break;
        }
        //銷燬資源
        imagedestroy($info['res']);
        imagedestroy($img);
    }

    /**
     * [getInfo 獲取圖片信息]
     * @author DaiChong
     * @DateTime 2019-05-23
     * @param    url $name 圖片地址
     * @return   array
     */
    public static function getInfo($name)
    {
        $info = getimagesize($name);

        $width = $info[0];
        $height = $info[1];
        $mime = $info['mime'];
        switch ($mime) {
            case 'image/jpeg':
                $res = imagecreatefromjpeg($name);
                break;
            case 'image/gif':
                $res = imagecreatefromgif($name);
                break;
            case 'image/png':
                $res = imagecreatefrompng($name);
                break;
            case 'image/wbmp':
                $res = imagecreatefromwbmp($name);
                break;
        }
        return array('width' => $width, 'height' => $height, 'res' => $res);
    }

}

總結

CreatePoster類可以完成圖片合成、圖片文字合成、合成文字處理等大部分需求,平時開發諸如海報二維碼等需求時可以使用此類。

合成效果:
合成效果圖以上便是簡易的頭像合成流程,等把國旗圖好好摳出來後,就可以幫身邊沒有帶上國旗頭像的胖友改頭像了~~另,很多爆款活動都可以動手copy一下的,有些可能就幾行代碼,不要怕難動手哦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章