123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- <?php
- // +----------------------------------------------------------------------
- // | Niucloud-admin 企业快速开发的saas管理平台
- // +----------------------------------------------------------------------
- // | 官方网址:https://www.niucloud.com
- // +----------------------------------------------------------------------
- // | niucloud团队 版权所有 开源版本可自由商用
- // +----------------------------------------------------------------------
- // | Author: Niucloud Team
- // +----------------------------------------------------------------------
- namespace core\poster;
- use Kkokk\Poster\Facades\Poster as PosterInstance;
- class Poster extends BasePoster
- {
- /**
- * @param array $config
- * @return void
- */
- protected function initialize(array $config = [])
- {
- parent::initialize($config);
- }
- /**
- * 创建海报
- * @param array $poster_data
- * @param string $dir
- * @param string $file_path
- * @return mixed|string
- * @throws \Exception
- */
- public function createPoster(array $poster_data, string $dir, string $file_path)
- {
- $bg_type = $poster_data[ 'global' ][ 'bgType' ];
- $instance = PosterInstance::extension('gd')->config([ 'path' => realpath($dir) . DIRECTORY_SEPARATOR . $file_path ]);
- $bg_width = $poster_data[ 'global' ][ 'width' ];
- $bg_height = $poster_data[ 'global' ][ 'height' ];
- if ($bg_type == 'url' && !empty($poster_data[ 'global' ][ 'bgUrl' ]) && is_file($poster_data[ 'global' ][ 'bgUrl' ])) {
- $im = $instance->buildIm($bg_width, $bg_height)->buildImage([
- 'src' => $poster_data[ 'global' ][ 'bgUrl' ],
- // 'angle' => 80
- ], 0, 0, 0, 0, $bg_width, $bg_height);
- } else {
- $im = $instance->buildIm($bg_width, $bg_height, $this->getRgbColor($poster_data[ 'global' ][ 'bgColor' ]));
- }
- $align_array = [
- 'center', 'left', 'right', 'top', 'bottom'
- ];
- foreach ($poster_data[ 'value' ] as $k => $v) {
- $type = $v[ 'type' ];
- switch ($type) {
- case 'text':
- $font_size = ceil($v[ 'fontSize' ]);
- $default_font = 'static' . DIRECTORY_SEPARATOR . 'font' . DIRECTORY_SEPARATOR . 'SourceHanSansCN-Regular.ttf';
- $font = $v[ 'fontFamily' ] ? : $default_font;
- $content_list = $this->getText($v[ 'value' ], $font_size, $font, $v[ 'space' ] ?? 0, $v[ 'width' ], $v[ 'height' ], $v[ 'lineHeight' ] + $font_size);
- $base_y = $this->getX($v[ 'y' ]);
- if (is_array($base_y)) {
- $diff_height = count($content_list) * ( $v[ 'lineHeight' ] + $font_size );
- $again_y = $base_y[ 0 ];
- if ($again_y == 'center') {
- $base_y_num = ( $bg_height - $diff_height ) > 0 ? ( $bg_height - $diff_height ) / 2 : 0;
- } else if ($again_y == 'top') {
- $base_y_num = 0;
- } else {
- $base_y_num = $bg_height - $v[ 'height' ];
- }
- } else {
- $base_y_num = $base_y;
- }
- // if(in_array($base_y, $align_array)){
- // $diff_height = count($content_list)*($v[ 'lineHeight' ]+$font_size);
- // $base_y_num = ($bg_height-$diff_height) > 0 ? ($bg_height-$diff_height)/2 : 0;
- // }else{
- // $base_y_num = $base_y[0];
- // }
- foreach ($content_list as $ck => $content) {
- if ($ck == 0) {
- if ($v[ 'lineHeight' ] > 0) {
- $item_line = $v[ 'lineHeight' ] / 2;
- } else {
- $item_line = 0;
- }
- } else {
- $item_line = $v[ 'lineHeight' ] + $font_size;
- }
- $base_y_num += $item_line;
- //计算文本框宽度
- $im = $im->buildText($content, $this->getX($v[ 'x' ]), $base_y_num, $font_size, $this->getRgbColor($v[ 'fontColor' ]), $v[ 'width' ], $font, $v[ 'weight' ] ? 10 : null); # 合成文字
- }
- break;
- case 'image':
- if (is_file($v[ 'value' ])) {
- $im = $im->buildImage($v[ 'value' ], $this->getX($v[ 'x' ]), $this->getY($v[ 'y' ]), 0, 0, $v[ 'width' ], $v[ 'height' ], false, $v[ 'shape' ] ?? 'normal'); # 合成图片
- }
- break;
- case 'draw':
- if (!empty($v[ 'draw_type' ]) && $v[ 'draw_type' ] == 'Polygon') {
- $points = $v[ 'points' ];
- $im = $im->buildLine($points[ 0 ][ 0 ], $points[ 0 ][ 1 ], $points[ 2 ][ 0 ], $points[ 2 ][ 1 ], $this->getRgbColor($v[ 'bgColor' ]), 'filled_rectangle');
- }
- break;
- }
- }
- $path = $im->getPoster();
- return str_replace(DIRECTORY_SEPARATOR, '/', str_replace(realpath(''), '', $path[ 'url' ]));
- }
- public function getX($dst_x)
- {
- if (is_int($dst_x)) {
- return $dst_x;
- } else {
- return [ $dst_x, 0 ];
- }
- }
- public function getY($dst_y)
- {
- if (is_int($dst_y)) {
- return $dst_y;
- } else {
- return [ $dst_y, 0 ];
- }
- }
- public function getRgbColor($color)
- {
- $color = $color ? : '#FFFFFF';
- if (!str_contains($color, '#')) {
- $color = str_replace('rgba(', '', $color);
- $color = str_replace(')', '', $color);
- list($r, $g, $b) = explode(',', $color);
- list($r, $g, $b) = array_map(function($v) { return (int) $v; }, [ $r, $g, $b ]);
- } else {
- list($r, $g, $b) = sscanf($color, "#%02x%02x%02x");
- }
- return [ $r, $g, $b, 1 ];
- }
- /**
- * 获取高度限制过后的文本
- * @param $content
- * @param $fontSize
- * @param $font
- * @param $space
- * @param $max_ws
- * @param $max_hs
- * @param $line_height
- * @return mixed
- */
- public function getText($content, $fontSize, $font, $space, $max_ws, $max_hs, $line_height)
- {
- $calcSpace = $space > $fontSize ? ( $space - $fontSize ) : 0; // 获取间距计算值
- $fontSize = ( $fontSize * 3 ) / 4; // px 转化为 pt
- mb_internal_encoding('UTF-8'); // 设置编码
- // 这几个变量分别是 字体大小, 角度, 字体名称, 字符串, 预设宽度
- $contents = '';
- $contentsArr = [];
- $letter = [];
- $line = 1;
- $calcSpaceRes = 0;
- // 将字符串拆分成一个个单字 保存到数组 letter 中
- for ($i = 0; $i < mb_strlen($content); $i++) {
- $letter[] = mb_substr($content, $i, 1);
- }
- $textWidthArr = [];
- $contentStr = '';
- $line_num = 1;
- $total_width = 0;
- $content_list = [];
- foreach ($letter as $l) {
- $textStr = $contentStr . $l;
- $fontBox = imagettfbbox($fontSize, 0, $font, $textStr);
- $textWidth = abs($fontBox[ 2 ]) + $calcSpaceRes;
- $textWidthArr[ $line ] = $textWidth;
- // 判断拼接后的字符串是否超过预设的宽度
- if (( $textWidth > $max_ws ) && ( $contents !== '' )) {
- $line_num++;
- if (( $line_num * $line_height ) > $max_hs) {
- break;
- }
- $contents .= "\n";
- $contentStr = "";
- $line++;
- }
- if (empty($content_list[ $line_num - 1 ])) $content_list[ $line_num - 1 ] = '';
- $content_list[ $line_num - 1 ] .= $l;
- $contents .= $l;
- $contentStr .= $l;
- $line === 1 && $calcSpaceRes += $calcSpace;
- $text_width = max(array_values($textWidthArr));
- }
- return $content_list;
- }
- }
|