123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- <?php
- namespace QrCode\traits;
- trait Fill
- {
- //半角
- public function halfCorner($img, $x, $y, $s, $bgColor, $frontColor, $lt = true, $lb = true, $rb = true, $rt = true)
- {
- //左上半角
- if ($lt) {
- imagefilledarc($img, $x * $s, $y * $s, $s / 2, $s / 2, 0, 90, $frontColor, IMG_ARC_PIE);
- imagefilledarc($img, $x * $s + $s / 4, $y * $s + $s / 4, $s / 2, $s / 2, 180, 270, $bgColor, IMG_ARC_PIE);
- }
- //左下半角
- if ($lb) {
- imagefilledarc($img, $x * $s, ($y + 1) * $s, $s / 2, $s / 2, 270, 360, $frontColor, IMG_ARC_PIE);
- imagefilledarc($img, $x * $s + $s / 4, ($y + 1) * $s - $s / 4, $s / 2, $s / 2, 90, 180, $bgColor, IMG_ARC_PIE);
- }
- //右下半角
- if ($rb) {
- imagefilledarc($img, ($x + 1) * $s, ($y + 1) * $s, $s / 2, $s / 2, 180, 270, $frontColor, IMG_ARC_PIE);
- imagefilledarc($img, ($x + 1) * $s - $s / 4, ($y + 1) * $s - $s / 4, $s / 2, $s / 2, 0, 90, $bgColor, IMG_ARC_PIE);
- }
- //右上半角
- if ($rt) {
- imagefilledarc($img, ($x + 1) * $s, $y * $s, ($s / 2), ($s / 2), 90, 180, $frontColor, IMG_ARC_PIE);
- imagefilledarc($img, ($x + 1) * $s - ($s / 4), $y * $s + ($s / 4), ($s / 2), ($s / 2), 270, 360, $bgColor, IMG_ARC_PIE);
- }
- }
- //半圆
- public function halfRounded($img, $x, $y, $s, $color, $t = true, $l = true, $b = true, $r = true)
- {
- //上半圆
- if ($t) {
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 180, 270, $color, IMG_ARC_PIE);
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 270, 360, $color, IMG_ARC_PIE);
- imagefilledrectangle($img, $x * $s, ($y * $s) + ($s / 2), ($x + 1) * $s, ($y + 1) * $s, $color);
- }
- //左半圆
- if ($l) {
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 90, 180, $color, IMG_ARC_PIE);
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 180, 270, $color, IMG_ARC_PIE);
- imagefilledrectangle($img, ($x * $s) + ($s / 2), ($y * $s), ($x + 1) * $s, ($y + 1) * $s, $color);
- }
- //下半圆
- if ($b) {
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 0, 90, $color, IMG_ARC_PIE);
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 90, 180, $color, IMG_ARC_PIE);
- imagefilledrectangle($img, $x * $s, $y * $s, ($x + 1) * $s, ($y * $s) + ($s / 2), $color);
- }
- //右半圆
- if ($r) {
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 270, 360, $color, IMG_ARC_PIE);
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 0, 90, $color, IMG_ARC_PIE);
- imagefilledrectangle($img, $x * $s, $y * $s, ($x * $s) + ($s / 2), ($y + 1) * $s, $color);
- }
- }
- /**
- * 图片圆角
- */
- public function roundedCorner($img, $x, $y, $s, $color, $lt = true, $lb = true, $rb = true, $rt = true)
- {
- if ($lt) {
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 180, 270, $color, IMG_ARC_PIE);
- $values = array(($x + 1) * $s, ($y * $s), ($x + 1) * $s, ($y + 1) * $s, ($x * $s), ($y + 1) * $s,);
- $values1 = array(($x * $s), ($y + 1) * $s, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), ($x * $s), ($y * $s) + ($s / 2),);
- $values2 = array(($x * $s) + ($s / 2), ($y * $s) + ($s / 2), ($x * $s) + ($s / 2), ($y * $s), ($x + 1) * $s, ($y * $s),);
- imagefilledpolygon($img, $values, 3, $color);
- imagefilledpolygon($img, $values1, 3, $color);
- imagefilledpolygon($img, $values2, 3, $color);
- }
- if ($lb) {
- imagefilledarc($img, ($x * $s) + ($s / 2), ($y * $s) + ($s / 2), $s, $s, 90, 180, $color, IMG_ARC_PIE);
- $values = array($x * $s, $y * $s, $x * $s + $s, $y * $s, $x * $s + $s, ($y + 1) * $s,);
- $values1 = array($x * $s, $y * $s, $x * $s, $y * $s + ($s / 2), $x * $s + $s, $y * $s + ($s / 2),);
- $values2 = array($x * $s + ($s / 2), $y * $s + ($s / 2), $x * $s + ($s / 2), ($y + 1) * $s, $x * $s + $s, ($y + 1) * $s,);
- imagefilledpolygon($img, $values, 3, $color);
- imagefilledpolygon($img, $values1, 3, $color);
- imagefilledpolygon($img, $values2, 3, $color);
- }
- if ($rb) {
- imagefilledarc($img, ($x * $s) + ($s / 2), $y * $s + ($s / 2), $s, $s, 360, 90, $color, IMG_ARC_PIE);
- $values = array($x * $s, ($y + 1) * $s, $x * $s, $y * $s, ($x + 1) * $s, $y * $s,);
- $values1 = array($x * $s, ($y + 1) * $s, $x * $s + ($s / 2), $y * $s + ($s / 2), $x * $s + ($s / 2), ($y + 1) * $s,);
- $values2 = array($x * $s + ($s / 2), $y * $s + ($s / 2), ($x + 1) * $s, $y * $s, ($x + 1) * $s, $y * $s + ($s / 2),);
- imagefilledpolygon($img, $values, 3, $color);
- imagefilledpolygon($img, $values1, 3, $color);
- imagefilledpolygon($img, $values2, 3, $color);
- }
- if ($rt) {
- imagefilledarc($img, ($x * $s) + ($s / 2), $y * $s + ($s / 2), $s, $s, 270, 360, $color, IMG_ARC_PIE);
- $values = array($x * $s, $y * $s, $x * $s, $y * $s + $s, ($x + 1) * $s, $y * $s + $s,);
- $values1 = array($x * $s, $y * $s, $x * $s + ($s / 2), $y * $s, $x * $s + ($s / 2), $y * $s + ($s / 2),);
- $values2 = array($x * $s + ($s / 2), $y * $s + ($s / 2), ($x + 1) * $s, $y * $s + ($s / 2), ($x + 1) * $s, $y * $s + $s,);
- imagefilledpolygon($img, $values, 3, $color);
- imagefilledpolygon($img, $values1, 3, $color);
- imagefilledpolygon($img, $values2, 3, $color);
- }
- }
- /**
- * 缩放图片
- * @param type $im
- * @param type $maxwidth
- * @param type $maxheight
- * @return type
- */
- public function resizeImage($im, $maxwidth, $maxheight)
- {
- $picWidth = imagesx($im);
- $picHeight = imagesy($im);
- $newIM = imagecreatetruecolor($maxwidth, $maxheight);
- ImageCopyResampled($newIM, $im, 0, 0, 0, 0, $maxwidth, $maxheight, $picWidth, $picHeight);
- imagedestroy($im);
- return $newIM;
- }
- //增加背景
- public function imageAddBG($im, $bgPath)
- {
- //加载logo
- $ext = pathinfo($bgPath, PATHINFO_EXTENSION);
- if (empty($ext)) {
- return false;
- }
- switch (strtolower($ext)) {
- case 'jpg':
- $bgRes = @imagecreatefromjpeg($bgPath);
- break;
- case 'gif':
- $bgRes = @imagecreatefromgif($bgPath);
- break;
- case 'png':
- $bgRes = @imagecreatefrompng($bgPath);
- break;
- }
-
- return $this->imageAddBGRes($im, $bgRes);
- }
- /**
- * 添加背景,参数都是资源
- * @param resource $im 图片资源
- * @param resource $bgRes 背景图片
- * @return resource
- */
- public function imageAddBGRes($im, $bgRes)
- {
- //计算宽和高
- $w = imagesx($im);
- $h = imagesy($im);
- $bgw = imagesx($bgRes);
- $bgh = imagesy($bgRes);
- imagecopymerge($bgRes, $im, ($bgw / 2) - ($w / 2), ($bgh / 2) - ($h / 2), 0, 0, $w, $h, 100);
- imagedestroy($im);
- return $bgRes;
- }
- /**
- * 图片增加logo
- * @param resource $im 图片资源
- * @param resource $logo logo图
- * @param int $stroke 是否对logo进行描边
- * @return resource
- */
- public function imageAddLogo($im, $logo, $stroke = 1) {
- //加载logo
- $ext = pathinfo($logo, PATHINFO_EXTENSION);
- if (empty($ext)) {
- throw new \Exception('Unsupported image format');
- }
- switch (strtolower($ext)) {
- case 'jpg':
- $logoRes = @imagecreatefromjpeg($logo);
- break;
- case 'gif':
- $logoRes = @imagecreatefromgif($logo);
- break;
- case 'png':
- $logoRes = @imagecreatefrompng($logo);
- break;
- default:
- throw new \Exception('Unsupported image format');
- break;
- }
- return $this->imageAddLogoRes($im, $logoRes, $stroke);
- }
- /**
- * 通过图片资源生成
- * @param resource $im 图片资源
- * @param resource $logoRes Logo资源
- * @return resource
- */
- public function imageAddLogoRes($im, $logoRes, $stroke = 0) {
- //计算宽和高
- $w = imagesx($im);
- $h = imagesy($im);
- $logoRes = $this->resizeImage($logoRes, min(36, $w / 5), min(36, $h / 5));
- $srcWidth = imagesx($logoRes);
- $srcHeight = imagesy($logoRes);
- if($stroke) {
- //logo边框1 小
- $bor1 = ImageCreate($srcWidth + 2, $srcHeight + 2);
- ImageColorAllocate($bor1, 237, 234, 237);//背景色
- $bor1Width = imagesx($bor1);
- $bor1Height = imagesy($bor1);
- //logo边框2 中
- $bor2 = ImageCreate($bor1Width + 8, $bor1Height + 8);
- ImageColorAllocate($bor2, 255, 255, 255);//背景色
- $bor2_w = imagesx($bor2);
- $bor2_h = imagesy($bor2);
- //logo边框3 大
- $bor3 = ImageCreate($bor2_w + 2, $bor2_h + 2);
- ImageColorAllocate($bor3, 215, 215, 215);//背景色
- $bor3Width = imagesx($bor3);
- $bor3Height = imagesy($bor3);
- //圆角处理
- $rounder = new \QrCode\RoundedCorner('', 5);
- //二维码与logo边框3合并
- $bor3 = $rounder->round_it($bor3);
- imagecopymerge($im, $bor3, ($w / 2) - ($bor3Width / 2), ($h / 2) - ($bor3Height / 2), 0, 0, $bor3Width, $bor3Height, 100);
- imagedestroy($bor3);
- //二维码与logo边框2合并
- $bor2 = $rounder->round_it($bor2);
- imagecopymerge($im, $bor2, ($w / 2) - ($bor2_w / 2), ($h / 2) - ($bor2_h / 2), 0, 0, $bor2_w, $bor2_h, 100);
- imagedestroy($bor2);
- //二维码与logo边框1合并
- $bor1 = $rounder->round_it($bor1);
- imagecopymerge($im, $bor1, ($w / 2) - ($bor1Width / 2), ($h / 2) - ($bor1Height / 2), 0, 0, $bor1Width, $bor1Height, 100);
- imagedestroy($bor1);
- //二维码与logo合并
- $logoRes = $rounder->round_it($logoRes);
- }
- imagecopymerge($im, $logoRes, ($w / 2) - ($srcWidth / 2), ($h / 2) - ($srcHeight / 2), 0, 0, $srcWidth, $srcHeight, 100);
- imagedestroy($logoRes);
- return $im;
- }
- /**
- * 在二维码下边生成图片
- *
- * @param resource $im 图片资源
- * @param string $text 文字
- * @param int $fontSize 字体
- * @param string $fontPath 字体路径
- * @param array $options 选型
- * @return resource
- */
- public function imageAddText($im, $text, $fontSize = 14, $fontPath = '', $options = array())
- {
- $fontSize = $fontSize ?? 14;
- if (empty($options['bgColor'])) {
- $options['bgColor'] = '#FFFFFF';
- }
- if (empty($options['fontColor'])) {
- $options['fontColor'] = $options['frontColor'] ?? '#000000';
- }
- //计算宽和高
- $w = imagesx($im);
- $h = imagesy($im);
- $bgColor = $this->hex2rgb($options['bgColor']);
- $fontColor = $this->hex2rgb($options['fontColor']);
- //自动换行
- $text = $this->autoWrap($text, 0, $fontSize, $fontPath, $w);
- $box = $this->imageTTFBoxExtended($fontSize, 0, $fontPath, $text);
- $maxHeight = $h + $box['height'] + 20;
- $newIM = imagecreatetruecolor($w, $maxHeight);
- //背景色
- $background = imagecolorallocatealpha($newIM, $bgColor['r'], $bgColor['g'], $bgColor['b'], 100);
- imagefill($newIM, 0, 0, $background);
- imagecopymerge($newIM, $im, 0, 0, 0, 0, $w, $h, 100);
- $fontColor = imagecolorallocatealpha($newIM, $fontColor['r'], $fontColor['g'], $fontColor['b'], 50);
- imagettftext($newIM, $fontSize, 0, max(0, ($w - $box['width']) / 2), $h + 25, $fontColor, $fontPath, $text);
- imagedestroy($im);
- return $newIM;
- }
- /**
- * 获取文字的宽高
- *
- * @param int $size 字体大小
- * @param int $angle
- * @param string $fontPath 字体路径
- * @param string $text 文字
- * @return array
- */
- public function imageTTFBoxExtended($size, $angle, $fontPath, $text)
- {
- $box = imagettfbbox($size, $angle, $fontPath, $text);
- //calculate x baseline
- if ($box[0] >= -1) {
- $box['x'] = abs($box[0] + 1) * -1;
- } else {
- //$box['x'] = 0;
- $box['x'] = abs($box[0] + 2);
- }
- //calculate actual text width
- $box['width'] = abs($box[2] - $box[0]);
- if ($box[0] < -1) {
- $box['width'] = abs($box[2]) + abs($box[0]) - 1;
- }
- //calculate y baseline
- $box['y'] = abs($box[5] + 1);
- //calculate actual text height
- $box['height'] = abs($box[7]) - abs($box[1]);
- if ($box[3] > 0) {
- $box['height'] = abs($box[7] - $box[1]) - 1;
- }
- return $box;
- }
- /**
- * 文字自动换行
- *
- * @param int $fontSize [字体大小]
- * @param int $angle [角度]
- * @param string $fontFace [字体名称]
- * @param string $string [字符串]
- * @param int $width [预设宽度]
- */
- function autoWrap($text, $angle, $fontSize, $fontFace, $width)
- {
- $content = "";
- // 将字符串拆分成一个个单字 保存到数组 letter 中
- preg_match_all("/./u", $text, $arr);
- $letter = $arr[0];
- foreach ($letter as $l) {
- $testStr = $content . " " . $l;
- $testBox = imagettfbbox($fontSize, $angle, $fontFace, $testStr);
- // 判断拼接后的字符串是否超过预设的宽度
- if (($testBox[2] > $width) && ($content !== "")) {
- $content .= PHP_EOL;
- }
- $content .= $l;
- }
- return $content;
- }
- /**
- * 16进制颜色转换为RGB色值
- * @param string $hexColor 颜色值
- * @return array {r:, g:, b:}
- */
- public function hex2rgb($hexColor)
- {
- $color = str_replace('#', '', $hexColor);
- if (strlen($color) > 3) {
- $rgb = array(
- 'r' => hexdec(substr($color, 0, 2)),
- 'g' => hexdec(substr($color, 2, 2)),
- 'b' => hexdec(substr($color, 4, 2))
- );
- } else {
- $color = str_replace('#', '', $hexColor);
- $r = substr($color, 0, 1) . substr($color, 0, 1);
- $g = substr($color, 1, 1) . substr($color, 1, 1);
- $b = substr($color, 2, 1) . substr($color, 2, 1);
- $rgb = array(
- 'r' => hexdec($r),
- 'g' => hexdec($g),
- 'b' => hexdec($b)
- );
- }
- return $rgb;
- }
- }
|