環境準備
win10+php7+GD擴展,windows系統安裝擴展可以直接把php.ini文件中以下語句前的;
去掉:
extension=gd2
國旗文件(昨天拿ipad摳了一天沒摳下,所以這是截的別人頭像上的圖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 '  1.創建畫板(普通畫板用CreatePalette;圖像畫板用CreateImage)';
echo '<br />';
echo '  2.合併圖片(ImagesMerge)';
echo '<br />';
echo '  3.插入文字(CreateChars)';
echo '<br />';
echo '  4.插入劃線(CreateLine)';
echo '<br />';
echo '  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一下的,有些可能就幾行代碼,不要怕難動手哦。