Qrcode.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. namespace app\api\service;
  3. use Endroid\QrCode\ErrorCorrectionLevel;
  4. use Endroid\QrCode\QrCode as QrCoder;
  5. use think\facade\App;
  6. class Qrcode
  7. {
  8. protected $_qr;
  9. protected $_encoding = 'UTF-8'; // 编码类型
  10. protected $_size = 300; // 二维码大小
  11. protected $_logo = false; // 是否需要带logo的二维码
  12. protected $_logo_url = ''; // logo图片路径
  13. protected $_logo_size = 80; // logo大小
  14. protected $_title = false; // 是否需要二维码title
  15. protected $_title_content = ''; // title内容
  16. protected $_generate = 'writefile'; // display-直接显示 writefile-写入文件
  17. protected $_file_path = 'uploads/qrcode'; // 写入文件路径
  18. const MARGIN = 10; // 二维码内容相对于整张图片的外边距
  19. const WRITE_NAME = 'png'; // 写入文件的后缀名
  20. const FOREGROUND_COLOR = ['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]; // 前景色
  21. const BACKGROUND_COLOR = ['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]; // 背景色
  22. /**
  23. * QrcodeServer constructor.
  24. * @param $config
  25. */
  26. public function __construct($config = [])
  27. {
  28. isset($config['generate']) && $this->_generate = $config['generate'];
  29. isset($config['encoding']) && $this->_encoding = $config['encoding'];
  30. isset($config['size']) && $this->_size = $config['size'];
  31. isset($config['logo']) && $this->_logo = $config['logo'];
  32. isset($config['logo_url']) && $this->_logo_url = $config['logo_url'];
  33. isset($config['logo_size']) && $this->_logo_size = $config['logo_size'];
  34. isset($config['title']) && $this->_title = $config['title'];
  35. isset($config['title_content']) && $this->_title_content = $config['title_content'];
  36. isset($config['file_path']) && $this->_file_path = $config['file_path'];
  37. }
  38. /**
  39. * 生成二维码
  40. * @param $content
  41. * @return array|string
  42. * @throws \Endroid\QrCode\Exception\InvalidPathException
  43. */
  44. public function createServer($content)
  45. {
  46. $this->_qr = new Qrcoder($content);
  47. $this->_qr->setSize($this->_size);
  48. $this->_qr->setWriterByName(self::WRITE_NAME);
  49. $this->_qr->setMargin(self::MARGIN);
  50. $this->_qr->setEncoding($this->_encoding);
  51. $this->_qr->setErrorCorrectionLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::HIGH)); // 容错率
  52. $this->_qr->setForegroundColor(self::FOREGROUND_COLOR);
  53. $this->_qr->setBackgroundColor(self::BACKGROUND_COLOR);
  54. // 是否需要title
  55. if ($this->_title) {
  56. $this->_qr->setLabel($this->_title_content, 16, null, LabelAlignment::CENTER);
  57. }
  58. // 是否需要logo
  59. if ($this->_logo) {
  60. $this->_qr->setLogoPath($this->_logo_url);
  61. $this->_qr->setLogoWidth($this->_logo_size);
  62. }
  63. $this->_qr->setValidateResult(false);
  64. if ($this->_generate == 'display') {
  65. // 展示二维码
  66. // 前端调用 例:<img src="http://localhost/qr.php?url=base64_url_string">
  67. header('Content-Type: ' . $this->_qr->getContentType());
  68. return $this->_qr->writeString();
  69. } else if ($this->_generate == 'writefile') {
  70. // 写入文件
  71. return $this->generateImg($this->_file_path);
  72. } else {
  73. return ['success' => false, 'message' => 'the generate type not found', 'data' => ''];
  74. }
  75. }
  76. /**
  77. * 生成文件
  78. *
  79. * @param $file_path
  80. * @return array
  81. */
  82. public function generateImg($file_path)
  83. {
  84. $file_name = uniqid() . '.' . self::WRITE_NAME;
  85. $save_path = App::getRootPath() . 'public/' . $file_path;
  86. if (!file_exists($save_path)) {
  87. mkdir($save_path, 0777, true);
  88. }
  89. try {
  90. $save_file = $save_path . '/' . $file_name;
  91. $this->_qr->writeFile($save_file);
  92. // 添加logo
  93. $logo = 'logo.png';//准备好的logo图片
  94. $QR = $save_file;//已经生成的原始二维码图
  95. if ($logo !== FALSE) {
  96. $QR = imagecreatefromstring(file_get_contents($QR));
  97. $logo = imagecreatefromstring(file_get_contents($logo));
  98. $QR_width = imagesx($QR);//二维码图片宽度
  99. $QR_height = imagesy($QR);//二维码图片高度
  100. $logo_width = imagesx($logo);//logo图片宽度
  101. $logo_height = imagesy($logo);//logo图片高度
  102. $logo_qr_width = $QR_width / 5;
  103. $scale = $logo_width / $logo_qr_width;
  104. $logo_qr_height = $logo_height / $scale;
  105. $from_width = ($QR_width - $logo_qr_width) / 2;
  106. //重新组合图片并调整大小
  107. imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,
  108. $logo_qr_height, $logo_width, $logo_height);
  109. }
  110. //输出图片
  111. imagepng($QR, $save_file);
  112. // 数据返回
  113. $data = [
  114. 'url' => $file_path . '/' . $file_name,
  115. 'ext' => self::WRITE_NAME,
  116. ];
  117. return ['success' => true, 'message' => 'write qrimg success', 'data' => $data];
  118. } catch (\Exception $e) {
  119. return ['success' => false, 'message' => $e->getMessage(), 'data' => ''];
  120. }
  121. }
  122. }