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; } }