PHP实现的创建带logo图标二维码生成类详解

这篇文章主要介绍了PHP实现的创建带logo图标二维码生成类,结合实例形式分析了可生成带logo的二维码工具类PHPQRCode.class.php相关参数、功能与使用技巧,需要的朋友可以参考下。

本文实例讲述了PHP实现的创建带logo图标二维码生成类,分享给大家供大家参考,具体如下:

这里介绍php实现创建二维码类,支持设置尺寸,加入LOGO,描边、圆角、透明度,等处理。提供完整代码,演示实例及详细参数说明,方便大家学习使用。

实现功能如下:

1.创建二维码

2.加入logo到二维码中

3.logo可描边

4.logo可圆角

5.logo可设透明度

6.logo图片及输出图片类型支持png,jpg,gif格式

7.可设置输出图片质量

设定参数说明:

ecc 二维码质量 L-smallest, M, Q, H-best

size 二维码尺寸 1-50

dest_file 生成的二维码图片路径

quality 生成的图片质量

logo logo路径,为空表示不加入logo

logo_size logo尺寸,null表示按二维码尺寸比例自动计算

logo_outline_size logo描边尺寸,null表示按logo尺寸按比例自动计算

logo_outline_color logo描边颜色

logo_opacity logo不透明度 0-100

logo_radius logo圆角角度 0-30

代码如下:

PHPQRCode.class.php

  1. <?php
  2. require_once dirname(__FILE__)."/qrcode/qrlib.php";
  3. /**
  4. * PHP创建二维码类
  5. * Date: 2018-03-18
  6. * Author: fdipzone
  7. * Version: 1.0
  8. *
  9. * Description:
  10. * PHP实现创建二维码类,支持设置尺寸,加入LOGO,圆角,透明度,等处理。
  11. *
  12. * Func:
  13. * public set_config 设定配置
  14. * public generate 创建二维码
  15. * private create_qrcode 创建纯二维码图片
  16. * private add_logo 合拼纯二维码图片与logo图片
  17. * private image_outline 图片对象进行描边
  18. * private image_fillet 图片对象进行圆角处理
  19. * private imagecopymerge_alpha 合拼图片并保留各自透明度
  20. * private create_dirs 创建目录
  21. * private hex2rgb hex颜色转rgb颜色
  22. * private get_file_ext 获取图片类型
  23. */
  24. class PHPQRCode{ // class start
  25. /** 默认设定 */
  26. private $_config = array(
  27. 'ecc' => 'H', // 二维码质量 L-smallest, M, Q, H-best
  28. 'size' => 15, // 二维码尺寸 1-50
  29. 'dest_file' => 'qrcode.png', // 创建的二维码路径
  30. 'quality' => 100, // 图片质量
  31. 'logo' => '', // logo路径,为空表示没有logo
  32. 'logo_size' => null, // logo尺寸,null表示按二维码尺寸比例自动计算
  33. 'logo_outline_size' => null, // logo描边尺寸,null表示按logo尺寸按比例自动计算
  34. 'logo_outline_color' => '#FFFFFF', // logo描边颜色
  35. 'logo_opacity' => 100, // logo不透明度 0-100
  36. 'logo_radius' => 0, // logo圆角角度 0-30
  37. );
  38. /**
  39. * 设定配置
  40. * @param Array $config 配置内容
  41. */
  42. public function set_config($config){
  43. // 允许设定的配置
  44. $config_keys = array_keys($this->_config);
  45. // 获取传入的配置,写入设定
  46. foreach($config_keys as $k=>$v){
  47. if(isset($config[$v])){
  48. $this->_config[$v] = $config[$v];
  49. }
  50. }
  51. }
  52. /**
  53. * 创建二维码
  54. * @param String $data 二维码内容
  55. * @return String
  56. */
  57. public function generate($data){
  58. // 创建临时二维码图片
  59. $tmp_qrcode_file = $this->create_qrcode($data);
  60. // 合拼临时二维码图片与logo图片
  61. $this->add_logo($tmp_qrcode_file);
  62. // 删除临时二维码图片
  63. if($tmp_qrcode_file!='' && file_exists($tmp_qrcode_file)){
  64. unlink($tmp_qrcode_file);
  65. }
  66. return file_exists($this->_config['dest_file'])? $this->_config['dest_file'] : '';
  67. }
  68. /**
  69. * 创建临时二维码图片
  70. * @param String $data 二维码内容
  71. * @return String
  72. */
  73. private function create_qrcode($data){
  74. // 临时二维码图片
  75. $tmp_qrcode_file = dirname(__FILE__).'/tmp_qrcode_'.time().mt_rand(100,999).'.png';
  76. // 创建临时二维码
  77. QRcode::png($data, $tmp_qrcode_file, $this->_config['ecc'], $this->_config['size'], 2);
  78. // 返回临时二维码路径
  79. return file_exists($tmp_qrcode_file)? $tmp_qrcode_file : '';
  80. }
  81. /**
  82. * 合拼临时二维码图片与logo图片
  83. * @param String $tmp_qrcode_file 临时二维码图片
  84. */
  85. private function add_logo($tmp_qrcode_file){
  86. // 创建目标文件夹
  87. $this->create_dirs(dirname($this->_config['dest_file']));
  88. // 获取目标图片的类型
  89. $dest_ext = $this->get_file_ext($this->_config['dest_file']);
  90. // 需要加入logo
  91. if(file_exists($this->_config['logo'])){
  92. // 创建临时二维码图片对象
  93. $tmp_qrcode_img = imagecreatefrompng($tmp_qrcode_file);
  94. // 获取临时二维码图片尺寸
  95. list($qrcode_w, $qrcode_h, $qrcode_type) = getimagesize($tmp_qrcode_file);
  96. // 获取logo图片尺寸及类型
  97. list($logo_w, $logo_h, $logo_type) = getimagesize($this->_config['logo']);
  98. // 创建logo图片对象
  99. switch($logo_type){
  100. case 1: $logo_img = imagecreatefromgif($this->_config['logo']); break;
  101. case 2: $logo_img = imagecreatefromjpeg($this->_config['logo']); break;
  102. case 3: $logo_img = imagecreatefrompng($this->_config['logo']); break;
  103. default: return '';
  104. }
  105. // 设定logo图片合拼尺寸,没有设定则按比例自动计算
  106. $new_logo_w = isset($this->_config['logo_size'])? $this->_config['logo_size'] : (int)($qrcode_w/5);
  107. $new_logo_h = isset($this->_config['logo_size'])? $this->_config['logo_size'] : (int)($qrcode_h/5);
  108. // 按设定尺寸调整logo图片
  109. $new_logo_img = imagecreatetruecolor($new_logo_w, $new_logo_h);
  110. imagecopyresampled($new_logo_img, $logo_img, 0, 0, 0, 0, $new_logo_w, $new_logo_h, $logo_w, $logo_h);
  111. // 判断是否需要描边
  112. if(!isset($this->_config['logo_outline_size']) || $this->_config['logo_outline_size']>0){
  113. list($new_logo_img, $new_logo_w, $new_logo_h) = $this->image_outline($new_logo_img);
  114. }
  115. // 判断是否需要圆角处理
  116. if($this->_config['logo_radius']>0){
  117. $new_logo_img = $this->image_fillet($new_logo_img);
  118. }
  119. // 合拼logo与临时二维码
  120. $pos_x = ($qrcode_w-$new_logo_w)/2;
  121. $pos_y = ($qrcode_h-$new_logo_h)/2;
  122. imagealphablending($tmp_qrcode_img, true);
  123. // 合拼图片并保留各自透明度
  124. $dest_img = $this->imagecopymerge_alpha($tmp_qrcode_img, $new_logo_img, $pos_x, $pos_y, 0, 0, $new_logo_w, $new_logo_h, $this->_config['logo_opacity']);
  125. // 生成图片
  126. switch($dest_ext){
  127. case 1: imagegif($dest_img, $this->_config['dest_file'], $this->_config['quality']); break;
  128. case 2: imagejpeg($dest_img, $this->_config['dest_file'], $this->_config['quality']); break;
  129. case 3: imagepng($dest_img, $this->_config['dest_file'], (int)(($this->_config['quality']-1)/10)); break;
  130. }
  131. // 不需要加入logo
  132. }else{
  133. $dest_img = imagecreatefrompng($tmp_qrcode_file);
  134. // 生成图片
  135. switch($dest_ext){
  136. case 1: imagegif($dest_img, $this->_config['dest_file'], $this->_config['quality']); break;
  137. case 2: imagejpeg($dest_img, $this->_config['dest_file'], $this->_config['quality']); break;
  138. case 3: imagepng($dest_img, $this->_config['dest_file'], (int)(($this->_config['quality']-1)/10)); break;
  139. }
  140. }
  141. }
  142. /**
  143. * 对图片对象进行描边
  144. * @param Obj $img 图片对象
  145. * @return Array
  146. */
  147. private function image_outline($img){
  148. // 获取图片宽高
  149. $img_w = imagesx($img);
  150. $img_h = imagesy($img);
  151. // 计算描边尺寸,没有设定则按比例自动计算
  152. $bg_w = isset($this->_config['logo_outline_size'])? intval($img_w + $this->_config['logo_outline_size']) : $img_w + (int)($img_w/5);
  153. $bg_h = isset($this->_config['logo_outline_size'])? intval($img_h + $this->_config['logo_outline_size']) : $img_h + (int)($img_h/5);
  154. // 创建底图对象
  155. $bg_img = imagecreatetruecolor($bg_w, $bg_h);
  156. // 设置底图颜色
  157. $rgb = $this->hex2rgb($this->_config['logo_outline_color']);
  158. $bgcolor = imagecolorallocate($bg_img, $rgb['r'], $rgb['g'], $rgb['b']);
  159. // 填充底图颜色
  160. imagefill($bg_img, 0, 0, $bgcolor);
  161. // 合拼图片与底图,实现描边效果
  162. imagecopy($bg_img, $img, (int)(($bg_w-$img_w)/2), (int)(($bg_h-$img_h)/2), 0, 0, $img_w, $img_h);
  163. $img = $bg_img;
  164. return array($img, $bg_w, $bg_h);
  165. }
  166. /**
  167. * 对图片对象进行圆角处理
  168. * @param Obj $img 图片对象
  169. * @return Obj
  170. */
  171. private function image_fillet($img){
  172. // 获取图片宽高
  173. $img_w = imagesx($img);
  174. $img_h = imagesy($img);
  175. // 创建圆角图片对象
  176. $new_img = imagecreatetruecolor($img_w, $img_h);
  177. // 保存透明通道
  178. imagesavealpha($new_img, true);
  179. // 填充圆角图片
  180. $bg = imagecolorallocatealpha($new_img, 255, 255, 255, 127);
  181. imagefill($new_img, 0, 0, $bg);
  182. // 圆角半径
  183. $r = $this->_config['logo_radius'];
  184. // 执行圆角处理
  185. for($x=0; $x<$img_w; $x++){
  186. for($y=0; $y<$img_h; $y++){
  187. $rgb = imagecolorat($img, $x, $y);
  188. // 不在图片四角范围,直接画图
  189. if(($x>=$r && $x<=($img_w-$r)) || ($y>=$r && $y<=($img_h-$r))){
  190. imagesetpixel($new_img, $x, $y, $rgb);
  191. // 在图片四角范围,选择画图
  192. }else{
  193. // 上左
  194. $ox = $r; // 圆心x坐标
  195. $oy = $r; // 圆心y坐标
  196. if( ( ($x-$ox)*($x-$ox) + ($y-$oy)*($y-$oy) ) <= ($r*$r) ){
  197. imagesetpixel($new_img, $x, $y, $rgb);
  198. }
  199. // 上右
  200. $ox = $img_w-$r; // 圆心x坐标
  201. $oy = $r; // 圆心y坐标
  202. if( ( ($x-$ox)*($x-$ox) + ($y-$oy)*($y-$oy) ) <= ($r*$r) ){
  203. imagesetpixel($new_img, $x, $y, $rgb);
  204. }
  205. // 下左
  206. $ox = $r; // 圆心x坐标
  207. $oy = $img_h-$r; // 圆心y坐标
  208. if( ( ($x-$ox)*($x-$ox) + ($y-$oy)*($y-$oy) ) <= ($r*$r) ){
  209. imagesetpixel($new_img, $x, $y, $rgb);
  210. }
  211. // 下右
  212. $ox = $img_w-$r; // 圆心x坐标
  213. $oy = $img_h-$r; // 圆心y坐标
  214. if( ( ($x-$ox)*($x-$ox) + ($y-$oy)*($y-$oy) ) <= ($r*$r) ){
  215. imagesetpixel($new_img, $x, $y, $rgb);
  216. }
  217. }
  218. }
  219. }
  220. return $new_img;
  221. }
  222. // 合拼图片并保留各自透明度
  223. private function imagecopymerge_alpha($dest_img, $src_img, $pos_x, $pos_y, $src_x, $src_y, $src_w, $src_h, $opacity){
  224. $w = imagesx($src_img);
  225. $h = imagesy($src_img);
  226. $tmp_img = imagecreatetruecolor($src_w, $src_h);
  227. imagecopy($tmp_img, $dest_img, 0, 0, $pos_x, $pos_y, $src_w, $src_h);
  228. imagecopy($tmp_img, $src_img, 0, 0, $src_x, $src_y, $src_w, $src_h);
  229. imagecopymerge($dest_img, $tmp_img, $pos_x, $pos_y, $src_x, $src_y, $src_w, $src_h, $opacity);
  230. return $dest_img;
  231. }
  232. /**
  233. * 创建目录
  234. * @param String $path
  235. * @return Boolean
  236. */
  237. private function create_dirs($path){
  238. if(!is_dir($path)){
  239. return mkdir($path, 0777, true);
  240. }
  241. return true;
  242. }
  243. /** hex颜色转rgb颜色
  244. * @param String $color hex颜色
  245. * @return Array
  246. */
  247. private function hex2rgb($hexcolor){
  248. $color = str_replace('#', '', $hexcolor);
  249. if (strlen($color) > 3) {
  250. $rgb = array(
  251. 'r' => hexdec(substr($color, 0, 2)),
  252. 'g' => hexdec(substr($color, 2, 2)),
  253. 'b' => hexdec(substr($color, 4, 2))
  254. );
  255. } else {
  256. $r = substr($color, 0, 1) . substr($color, 0, 1);
  257. $g = substr($color, 1, 1) . substr($color, 1, 1);
  258. $b = substr($color, 2, 1) . substr($color, 2, 1);
  259. $rgb = array(
  260. 'r' => hexdec($r),
  261. 'g' => hexdec($g),
  262. 'b' => hexdec($b)
  263. );
  264. }
  265. return $rgb;
  266. }
  267. /** 获取图片类型
  268. * @param String $file 图片路径
  269. * @return int
  270. */
  271. private function get_file_ext($file){
  272. $filename = basename($file);
  273. list($name, $ext)= explode('.', $filename);
  274. $ext_type = 0;
  275. switch(strtolower($ext)){
  276. case 'jpg':
  277. case 'jpeg':
  278. $ext_type = 2;
  279. break;
  280. case 'gif':
  281. $ext_type = 1;
  282. break;
  283. case 'png':
  284. $ext_type = 3;
  285. break;
  286. }
  287. return $ext_type;
  288. }
  289. } // class end
  290. ?>

demo.php

  1. <?php
  2. require 'PHPQRCode.class.php';
  3. $config = array(
  4. 'ecc' => 'H', // L-smallest, M, Q, H-best
  5. 'size' => 12, // 1-50
  6. 'dest_file' => 'qrcode.png',
  7. 'quality' => 90,
  8. 'logo' => 'logo.jpg',
  9. 'logo_size' => 100,
  10. 'logo_outline_size' => 20,
  11. 'logo_outline_color' => '#FFFF00',
  12. 'logo_radius' => 15,
  13. 'logo_opacity' => 100,
  14. );
  15. // 二维码内容
  16. $data = 'https://www.phpfensi.com/';
  17. // 创建二维码类
  18. $oPHPQRCode = new PHPQRCode();
  19. // 设定配置
  20. $oPHPQRCode->set_config($config);
  21. // 创建二维码
  22. $qrcode = $oPHPQRCode->generate($data);
  23. // 显示二维码
  24. echo '<img src="'.$qrcode.'?t='.time().'">';
  25. ?>