代码
composer require endroid/qr-code
<?php
namespace App\Service;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
use Endroid\QrCode\Writer\PngWriter;
class ImageService{
public static function create($config = [], $filename = ''){
$imageDefault = array(
'left' => 0,
'top' => 0,
'width' => 100,
'height' => 100,
'opacity' => 100,
'circle' => 0
);
$qrcodeDefault = [
'text' => 'qrcode content',
'size' => 100,
'margin' => 2,
'left' => 0,
'top' => 0,
'color' => '0,0,0'
];
$textDefault = array(
'text' => '',
'left' => 0,
'top' => 0,
'align' => '',
'font-size' => 32,
'color' => '0,0,0',
'angle' => 0,
'font-path' => RUNTIME_PATH . '/font/SourceHanSansCN-Regular.otf'
);
$background = $config['background'];
$backgroundInfo = getimagesize($background);
$backgroundFun = 'imagecreatefrom'.image_type_to_extension($backgroundInfo[2], false);
$background = $backgroundFun($background);
$backgroundWidth = imagesx($background);
$backgroundHeight = imagesy($background);
$imageRes = imageCreatetruecolor($backgroundWidth,$backgroundHeight);
$color = imagecolorallocate($imageRes, 0, 0, 0);
imagefill($imageRes, 0, 0, $color);
imagecopyresampled($imageRes,$background,0,0,0,0,imagesx($background),imagesy($background),imagesx($background),imagesy($background));
if (!empty($config['qrcode'])){
foreach ($config['qrcode'] as $item){
$item = array_merge($qrcodeDefault, $item);
list($red,$green,$blue) = explode(',', $item['color']);
$qrcode = Builder::create()
->writer(new PngWriter())
->writerOptions([])
->data($item['text'])
->encoding(new Encoding('UTF-8'))
->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
->size($item['size'])
->foregroundColor(new Color(intval($red), intval($green), intval($blue)))
->margin($item['margin'])
->roundBlockSizeMode(new RoundBlockSizeModeMargin())
->build();
$baseImage = imagecreatefromstring($qrcode->getString());
imagecopymerge($imageRes, $baseImage, $item['left'],$item['top'],0,0, $item['size'], $item['size'],100);
}
}
if(!empty($config['image'])){
foreach ($config['image'] as $key => $val) {
$val = array_merge($imageDefault,$val);
$info = getimagesize($val['url']);
if($val['circle']){
$canvas = self::imageRadius($val['url'], $val['width']/2);
}else{
$function = 'imagecreatefrom'.image_type_to_extension($info[2], false);
$res = $function($val['url']);
$resWidth = $info[0];
$resHeight = $info[1];
$canvas=imagecreatetruecolor($val['width'], $val['height']);
imagefill($canvas, 0, 0, $color);
imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight);
}
$val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
$val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top'];
imagecopymerge($imageRes,$canvas, $val['left'], $val['top'], 0, 0, $val['width'], $val['height'],$val['opacity']);
imagedestroy($canvas);
}
}
if(!empty($config['text'])){
foreach ($config['text'] as $key => $val) {
$val = array_merge($textDefault,$val);
list($R,$G,$B) = explode(',', $val['color']);
$color = imagecolorallocate($imageRes, $R, $G, $B);
$arr = imagettfbbox($val['font-size'],0,$val['font-path'],$val['text']);
$text_height = $arr[3] - $arr[5];
if ($val['align'] == 'center'){
$text_width = $arr[2]-$arr[0];
$val['left'] = ($backgroundWidth - $text_width)/2;
}else{
$val['left'] = $val['left'] < 0 ? $backgroundWidth- abs($val['left']):$val['left'];
}
$val['top'] = $val['top'] < 0 ? $backgroundHeight- abs($val['top']) : $val['top'];
$val['top'] += $text_height;
imagettftext($imageRes,$val['font-size'],$val['angle'],$val['left'],$val['top'],$color,$val['font-path'],$val['text']);
}
}
if(!empty($filename)){
$res = imagepng($imageRes, RUNTIME_PATH.'/'. $filename,90);
imagedestroy($imageRes);
if(!$res) return false;
return $filename;
}else{
ob_start();
imagepng($imageRes);
$string = strval(ob_get_contents());
ob_end_clean();
return 'data:image/png;base64,'.base64_encode($string);
}
}
public static function imageRadius($image, $radius = null){
$logo = imagecreatefromstring(file_get_contents($image));
$height = $width = min(imagesx($logo), imagesy($logo));
if ($radius && $width / 2 < $radius){
$new_w = $new_h = $radius * 2;
$new = imagecreatetruecolor($new_w, $new_h);
imagecopyresized($new, $logo,0, 0,0, 0, $new_w, $new_h, $width, $height);
$width = $height = $new_w;
$logo = $new;
}
$canvas = imagecreatetruecolor($width, $height);
$color = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
imagesavealpha($canvas, true);
imagealphablending($canvas, false);
imagefill($canvas, 0, 0, $color);
imageColorTransparent($canvas, $color);
$r = $width / 2;
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$rgb_color = imagecolorat($logo, $x, $y);
if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r) < ($r * $r)))) {
imagesetpixel($canvas, $x, $y, $rgb_color);
}
}
}
imagedestroy($logo);
return $canvas;
}
}
用法
$config = array(
'image'=>array(
array(
'url' => 'https://img.w7.cc/07/cb/0e/e6/02/33/59/b7/42/e2/5b/d4/a5/04/09/c0.png',
'left' => 280,
'top' => 445,
'width' => 190,
'height' => 190,
'opacity' => 100,
'circle' => 1
)
),
'qrcode' => [
[
'text' => 'qrcode content',
'size' => 176,
'margin' => 2,
'left' => 98,
'top' => 406,
]
],
'text' => [
[
'text' => '一言网络科技有限公司',
'font-size' => 16,
'align' => 'center',
'top' => 355,
]
],
'background'=> '/shop_poster_bg.png'
);
$src = App\Model\Service\ImageService::create($config);
|