PosterService.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace app\common\service\qrcode;
  3. use app\common\model\settings\Setting as SettingModel;
  4. use Endroid\QrCode\QrCode;
  5. use Grafika\Color;
  6. use Grafika\Grafika;
  7. use app\common\model\plus\agent\Setting;
  8. /**
  9. * 分销二维码
  10. */
  11. class PosterService extends Base
  12. {
  13. // 分销商用户信息
  14. private $agent;
  15. // 分销商海报设置
  16. private $config;
  17. // 来源
  18. private $source;
  19. /**
  20. * 构造方法
  21. */
  22. public function __construct($agent, $source)
  23. {
  24. parent::__construct();
  25. // 分销商用户信息
  26. $this->agent = $agent;
  27. $this->source = $source;
  28. // 分销商海报设置
  29. $this->config = Setting::getItem('qrcode', $agent['app_id']);
  30. }
  31. /**
  32. * 获取分销二维码
  33. */
  34. public function getImage()
  35. {
  36. if (file_exists($this->getPosterPath())) {
  37. return $this->getPosterUrl();
  38. }
  39. // 小程序id
  40. $appId = $this->agent['app_id'];
  41. // 1. 下载背景图
  42. $backdrop = $this->saveTempImage($appId, $this->config['backdrop']['src'], 'backdrop');
  43. // 2. 下载用户头像
  44. $avatarUrl = $this->saveTempImage($appId, $this->agent['user']['avatarUrl'], 'avatar');
  45. $qrcode = null;
  46. if($this->source == 'wx') {
  47. // 3. 下载小程序码
  48. $scene = 'uid:' . $this->agent['user_id'];
  49. $qrcode = $this->saveQrcode($appId, $scene, 'pages/index/index');
  50. } else if($this->source == 'mp' || $this->source == 'h5'){
  51. $scene = 'uid:' . $this->agent['user_id'];
  52. $url = base_url().'h5/pages/index/index?referee_id='.$this->agent['user_id'].'&app_id='.$appId;
  53. $qrcode = new QrCode($url);
  54. $qrcode = $this->saveMpQrcode($qrcode, $appId, $scene, 'image_mp');
  55. } else if($this->source == 'app'){
  56. $appshare = SettingModel::getItem('appshare');
  57. if($appshare['type'] == 1){
  58. $down_url = $appshare['open_site']. '?app_id='.$this->agent['app_id'].'&referee_id=' .$this->agent['user_id'];
  59. }else{
  60. //下载页
  61. if($appshare['bind_type'] == 1){
  62. $down_url = $appshare['down_url'];
  63. }else{
  64. $down_url = base_url(). "/index.php/api/user.useropen/invite?app_id=".$this->agent['app_id']."&referee_id=" .$this->agent['user_id'];
  65. }
  66. }
  67. $scene = 'uid:' . $this->agent['user_id'];
  68. $qrcode = new QrCode($down_url);
  69. $qrcode = $this->saveMpQrcode($qrcode, $appId, $scene, 'image_app');
  70. }
  71. // 4. 拼接海报图
  72. return $this->savePoster($backdrop, $avatarUrl, $qrcode);
  73. }
  74. /**
  75. * 海报图文件路径
  76. */
  77. private function getPosterPath()
  78. {
  79. // 保存路径
  80. $tempPath = root_path('public') . 'temp/' . $this->agent['app_id'] . '/' . $this->source. '/';
  81. !is_dir($tempPath) && mkdir($tempPath, 0755, true);
  82. return $tempPath . $this->getPosterName();
  83. }
  84. /**
  85. * 海报图文件名称
  86. */
  87. private function getPosterName()
  88. {
  89. return 'poster_' . md5($this->agent['user_id']) . '.png';
  90. }
  91. /**
  92. * 海报图url
  93. */
  94. private function getPosterUrl()
  95. {
  96. return \base_url() . 'temp/' . $this->agent['app_id'] . '/' .$this->source . '/' . $this->getPosterName() . '?t=' . time();
  97. }
  98. /**
  99. * 拼接海报图
  100. */
  101. private function savePoster($backdrop, $avatarUrl, $qrcode)
  102. {
  103. // 实例化图像编辑器
  104. $editor = Grafika::createEditor(['Gd']);
  105. // 打开海报背景图
  106. $editor->open($backdropImage, $backdrop);
  107. // 生成圆形用户头像
  108. $this->config['avatar']['style'] === 'circle' && $this->circular($avatarUrl, $avatarUrl);
  109. // 打开用户头像
  110. $editor->open($avatarImage, $avatarUrl);
  111. // 重设用户头像宽高
  112. $avatarWidth = $this->config['avatar']['width'] * 2;
  113. $editor->resizeExact($avatarImage, $avatarWidth, $avatarWidth);
  114. // 用户头像添加到背景图
  115. $avatarX = $this->config['avatar']['left'] * 2;
  116. $avatarY = $this->config['avatar']['top'] * 2;
  117. $editor->blend($backdropImage, $avatarImage, 'normal', 1.0, 'top-left', $avatarX, $avatarY);
  118. // 生成圆形小程序码,仅小程序支持
  119. if($this->source == 'wx'){
  120. $this->config['qrcode']['style'] === 'circle' && $this->circular($qrcode, $qrcode);
  121. }
  122. // 打开小程序码
  123. $editor->open($qrcodeImage, $qrcode);
  124. // 重设小程序码宽高
  125. $qrcodeWidth = $this->config['qrcode']['width'] * 2;
  126. $editor->resizeExact($qrcodeImage, $qrcodeWidth, $qrcodeWidth);
  127. // 小程序码添加到背景图
  128. $qrcodeX = $this->config['qrcode']['left'] * 2;
  129. $qrcodeY = $this->config['qrcode']['top'] * 2;
  130. $editor->blend($backdropImage, $qrcodeImage, 'normal', 1.0, 'top-left', $qrcodeX, $qrcodeY);
  131. // 写入用户昵称
  132. $fontSize = $this->config['nickName']['fontSize'] * 2;
  133. $fontX = $this->config['nickName']['left'] * 2;
  134. $fontY = $this->config['nickName']['top'] * 2;
  135. $Color = new Color($this->config['nickName']['color']);
  136. $fontPath = Grafika::fontsDir() . '/' . 'st-heiti-light.ttc';
  137. $editor->text($backdropImage, $this->agent['user']['nickName'], $fontSize, $fontX, $fontY, $Color, $fontPath);
  138. // 保存图片
  139. $editor->save($backdropImage, $this->getPosterPath());
  140. return $this->getPosterUrl();
  141. }
  142. /**
  143. * 生成圆形图片
  144. */
  145. private function circular($imgpath, $saveName = '')
  146. {
  147. $srcImg = imagecreatefromstring(file_get_contents($imgpath));
  148. $w = imagesx($srcImg);
  149. $h = imagesy($srcImg);
  150. $w = $h = min($w, $h);
  151. $newImg = imagecreatetruecolor($w, $h);
  152. // 这一句一定要有
  153. imagesavealpha($newImg, true);
  154. // 拾取一个完全透明的颜色,最后一个参数127为全透明
  155. $bg = imagecolorallocatealpha($newImg, 255, 255, 255, 127);
  156. imagefill($newImg, 0, 0, $bg);
  157. $r = $w / 2; //圆半径
  158. for ($x = 0; $x < $w; $x++) {
  159. for ($y = 0; $y < $h; $y++) {
  160. $rgbColor = imagecolorat($srcImg, $x, $y);
  161. if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
  162. imagesetpixel($newImg, $x, $y, $rgbColor);
  163. }
  164. }
  165. }
  166. // 输出图片到文件
  167. imagepng($newImg, $saveName);
  168. // 释放空间
  169. imagedestroy($srcImg);
  170. imagedestroy($newImg);
  171. }
  172. }