DiyQRCode.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. namespace app\common\utility;
  3. use app\common\library\Redis;
  4. use think\Config;
  5. use Endroid\QrCode\QrCode;
  6. use EasyWeChat\Factory;
  7. use Symfony\Component\Cache\Simple\RedisCache;
  8. /**
  9. * 自定义永久二维码
  10. * Class DiyQRCode
  11. * @package app\common\utility
  12. */
  13. class DiyQRCode{
  14. /**
  15. * 二维码模板信息
  16. * @var array
  17. */
  18. private static $tpl_size = [
  19. 1 => [
  20. 'size' => 164, //二维码宽度
  21. 'x' => 376, //水印x
  22. 'y' => 35 //水印y
  23. ],
  24. 2 => [
  25. 'size' => 168, //二维码宽度
  26. 'x' => 374, //水印x
  27. 'y' => 33 //水印y
  28. ],
  29. 3 => [
  30. 'size' => 156, //二维码宽度
  31. 'x' => 372, //水印x
  32. 'y' => 46 //水印y
  33. ],
  34. 4 => [
  35. 'size' => 200, //二维码宽度
  36. 'x' => 356, //水印x
  37. 'y' => 15 //水印y
  38. ],
  39. 5 => [
  40. 'size' => 200, //二维码宽度
  41. 'x' => 356, //水印x
  42. 'y' => 15 //水印y
  43. ],
  44. 6 => [
  45. 'size' => 200, //二维码宽度
  46. 'x' => 356, //水印x
  47. 'y' => 15 //水印y
  48. ]
  49. ];
  50. /**
  51. * 跟进自定义模板创建二维码
  52. * @param $url
  53. * @param $tpl_id
  54. * @return string
  55. * @throws \Exception
  56. */
  57. public static function createTplQRCode($url,$tpl_id){
  58. $qrcode_save_path = ROOT_PATH.'public'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'qrcode'.DIRECTORY_SEPARATOR;
  59. $qrcode_tpl_path = ROOT_PATH . 'public'.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.'img'.DIRECTORY_SEPARATOR.'essay'.DIRECTORY_SEPARATOR.'qrcode_%s.png';
  60. if(!$tpl_id || !array_key_exists($tpl_id,self::$tpl_size)){
  61. throw new \Exception('获取模板ID失败');
  62. }
  63. $tpl_img = imagecreatefrompng(sprintf($qrcode_tpl_path,$tpl_id)); //底图
  64. $new_img = self::createThumbnail($url, self::$tpl_size[$tpl_id]['size'], self::$tpl_size[$tpl_id]['size']);
  65. imagecopymerge($tpl_img,$new_img, self::$tpl_size[$tpl_id]['x'], self::$tpl_size[$tpl_id]['y'], 0, 0, imagesx($new_img), imagesy($new_img), 100);
  66. if (!file_exists($qrcode_save_path)) { //创建文件夹
  67. mkdir($qrcode_save_path, 0700, true);
  68. clearstatcache();
  69. }
  70. $save_path = $qrcode_save_path .md5($url.$tpl_id).'.png';
  71. if(!file_exists($save_path)){
  72. if(!$res = imagepng($tpl_img, $save_path)){
  73. throw new \Exception('创建自定义二维码出错');
  74. }
  75. }
  76. imagedestroy($tpl_img);
  77. imagedestroy($new_img);
  78. $cdn_url = cdnurl("/uploads/qrcode/" .md5($url.$tpl_id).'.png');
  79. return $cdn_url;
  80. }
  81. /**
  82. * 创建纯二维码
  83. * @param $url
  84. * @param int $size
  85. * @return string
  86. */
  87. public static function createQRCodeByUrl($url,$size = 430){
  88. $qrcode_save_path = ROOT_PATH.'public'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'qrcode'.DIRECTORY_SEPARATOR;
  89. $save_common_path = 'common'.DIRECTORY_SEPARATOR;
  90. $qrcode_path = $qrcode_save_path.$save_common_path.md5($url).'.png';
  91. if(!file_exists($qrcode_path)){
  92. $qrCode = new QrCode($url);
  93. $qrCode->setSize($size); //二维码尺寸
  94. $qrCode->setWriterByName('png');
  95. $qrCode->setEncoding('UTF-8');
  96. $qrCode->setMargin(10);
  97. if (!file_exists($qrcode_save_path.$save_common_path)) { //创建文件夹
  98. mkdir($qrcode_save_path.$save_common_path, 0700, true);
  99. clearstatcache();
  100. }
  101. $qrCode->writeFile($qrcode_path);
  102. }
  103. $cdn_url = cdnurl("/uploads/qrcode/" .$save_common_path.md5($url).'.png');
  104. return $cdn_url;
  105. }
  106. /**
  107. * 获取自定义二维码路径
  108. * @param $url
  109. * @param null $tpl_id
  110. * @return array|string|null
  111. */
  112. public static function getTplPath($url,$tpl_id = null){
  113. $qrcode_save_path = ROOT_PATH.'public'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'qrcode'.DIRECTORY_SEPARATOR;
  114. if(empty($url)){
  115. return null;
  116. }
  117. if($tpl_id){
  118. if(file_exists($qrcode_save_path .md5($url.$tpl_id).'.png')){
  119. return cdnurl("/uploads/qrcode/" .md5($url.$tpl_id).'.png');
  120. }
  121. }else{
  122. $result = [];
  123. $tpl_ids = array_keys(self::$tpl_size);
  124. foreach($tpl_ids as $id){
  125. if(file_exists($qrcode_save_path .md5($url.$id).'.png')){
  126. $result[$id] = cdnurl("/uploads/qrcode/" .md5($url.$id).'.png');
  127. }
  128. }
  129. return $result;
  130. }
  131. }
  132. /**
  133. * 删除自定义二维码
  134. * @param $url
  135. * @param $tpl_id
  136. * @return bool
  137. */
  138. public static function unlinkQRCode($url,$tpl_id = null){
  139. $qrcode_save_path = ROOT_PATH.'public'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'qrcode'.DIRECTORY_SEPARATOR;
  140. if(empty($url)){
  141. return true;
  142. }
  143. //删除二维码模板
  144. if($tpl_id !== null){
  145. if(file_exists($qrcode_save_path .md5($url.$tpl_id).'.png')){
  146. @unlink($qrcode_save_path .md5($url.$tpl_id).'.png');
  147. }
  148. }else{
  149. $tpl_ids = array_keys(self::$tpl_size);
  150. foreach($tpl_ids as $id){
  151. if(file_exists($qrcode_save_path .md5($url.$id).'.png')){
  152. @unlink($qrcode_save_path .md5($url.$id).'.png');
  153. }
  154. }
  155. }
  156. //删除自定义二维码
  157. if(file_exists($qrcode_save_path.'common'.DIRECTORY_SEPARATOR.md5($url).'png')){
  158. @unlink($qrcode_save_path.'common'.DIRECTORY_SEPARATOR.md5($url).'png');
  159. }
  160. return true;
  161. }
  162. /**
  163. * 生成保持原图纵横比的缩略图,支持.png .jpg .gif
  164. * 缩略图类型统一为.png格式
  165. * @param $srcFile 原图像文件名称
  166. * @param $toW 缩略图宽
  167. * @param $toH 缩略图高
  168. * @return bool
  169. * @throws
  170. */
  171. private static function createThumbnail($srcFile, $toW, $toH){
  172. $info = "";
  173. //返回含有4个单元的数组,0-宽,1-高,2-图像类型,3-宽高的文本描述。
  174. //失败返回false并产生警告。
  175. if(strpos($srcFile,'http') !== 0){
  176. $srcFile = ROOT_PATH.'public'.$srcFile;
  177. }
  178. $data = getimagesize($srcFile, $info);
  179. if (!$data)
  180. return false;
  181. //将文件载入到资源变量im中
  182. switch ($data[2]) //1-GIF,2-JPG,3-PNG
  183. {
  184. case 1:
  185. if(!function_exists("imagecreatefromgif")) {
  186. throw new \Exception('the GD can\'t support .gif, please use .jpeg or .png!');
  187. }
  188. $im = imagecreatefromgif($srcFile);
  189. break;
  190. case 2:
  191. if(!function_exists("imagecreatefromjpeg")) {
  192. throw new \Exception('the GD can\'t support .jpeg, please use other picture!');
  193. }
  194. $im = imagecreatefromjpeg($srcFile);
  195. break;
  196. case 3:
  197. $im = imagecreatefrompng($srcFile);
  198. break;
  199. }
  200. //计算缩略图的宽高
  201. $srcW = imagesx($im);
  202. $srcH = imagesy($im);
  203. $toWH = $toW / $toH;
  204. $srcWH = $srcW / $srcH;
  205. if ($toWH <= $srcWH) {
  206. $ftoW = $toW;
  207. $ftoH = (int)($ftoW * ($srcH / $srcW));
  208. }else{
  209. $ftoH = $toH;
  210. $ftoW = (int)($ftoH * ($srcW / $srcH));
  211. }
  212. if (function_exists("imagecreatetruecolor")) {
  213. $ni = imagecreatetruecolor($ftoW, $ftoH); //新建一个真彩色图像
  214. if ($ni){
  215. //重采样拷贝部分图像并调整大小 可保持较好的清晰度
  216. imagecopyresampled($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
  217. }else{
  218. //拷贝部分图像并调整大小
  219. $ni = imagecreate($ftoW, $ftoH);
  220. imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
  221. }
  222. }else{
  223. $ni = imagecreate($ftoW, $ftoH);
  224. imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH);
  225. }
  226. ImageDestroy($im);
  227. return $ni;
  228. }
  229. }