转载至 https://www.cnblogs.com/mingc/p/7943999.html
这篇文章里用的两个二维码扩展都有些问题和麻烦:phpqrcode(生成二维码)的源码有点小 bug; 而 php-zbarcode(识别二维码)需要其他开源套件和扩展模块的支持,编译起来很容易出问题,只支持 php5,而且 3 年多没维护,目测作者已放弃。对于不爱折腾开发环境的人太不方便。在 github 找到两个扩展,本人推荐:
- endroid/qrcode: 生成二维码,第三方包,支持 Composer。ReadMe 里有简明的 Demo,可以快速上手。不再另说了。
- php-qrcode-detector-decoder: 识别二维码,第三方包,支持 Composer。只需要 php5.6 以上和 GD 库支持。ReadMe 里也有简明的 Demo,可以快速上手。不再另说。
2018-02-04 23:28:30 更新:使用 apt 安装 zbar
编译安装 zbar 还是有毛病,很容易出问题。Ubuntu 官方源有个 zbar-tools,也就是 zbar。推荐朋友们用 apt 安装,一条命令搞定:
1 | sudo apt-get install zbar-tools |
我的系统是 Ubuntu 17.10.1,官方源有 zbar-tools,所以直接装了。装好 zbar 之后就可以使用 zbarimg path/to/your_qrcode.png 识别二维码了。如果你的 ppa 源里没有 zbar-tools、并且也没找到其他可用的ppa,那还是按照本文的 “六、安装 zbar” 部分尝试编译安装吧。
一、php 生成 qr code 二维码
phpqrcode 是由 php 编写的、可以生成 QR Code 二维码的第三方包。官网有很多例子可以参考,使用起来很简单,2 行代码。
1 2 3 4 5 6 7 8 9 10 11 12 | <?php // 1. 使用官网包 require './phpqrcode/qrlib.php' ; QRcode::png( 'http://github.com' , 'qrcode.png' , QR_ECLEVEL_L, 8, 4, false); // 该方法的最后一个参数有Bug,写 TRUE 时(保存并打印)并不会打印显示,需要修改源码 // QRcode::png('123', './qrcode.png', QR_ECLEVEL_L, 4, 4, TRUE); // 2. 使用composer包 // aferrandini/phpqrcode 这个包在packagist.org上排名第一,是根据官网打包的,不过Bug似乎也好好的在那儿~~。 // 其他类似的composer包还有很多,按需求找吧~~ |
二、jquery 生成 qr code 二维码
jquery.qrcode.js 是前端生成 QR Code 二维码的插件库。下面是我参考 jquery.qrcode.js 在 github 仓库上一个 example 写的。看代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <! DOCTYPE html> < html > < head > < meta charset="utf-8"> < title >QR Code</ title > < script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></ script > < script type="text/javascript" src="./js/jquery.qrcode.js"></ script > < script type="text/javascript" src="./js/qrcode.js"></ script > </ head > < body > < p >快速渲染:</ p > < div id="qrcode"></ div > < p >table渲染:</ p > < div id="qrcodeTable"></ div > < p >canvas渲染:</ p > < div id="qrcodeCanvas"></ div > < p >设置宽高:</ p > < div id="qrcodeResize"></ div > <!-- -------------------------------------------------------- --> < script > // 快速渲染 $('#qrcode').qrcode("http://github.com"); // table渲染 $('#qrcodeTable').qrcode({ render : "table", text : "http://github.com" }); // canvas渲染 $('#qrcodeCanvas').qrcode({ render : "canvas", text : "http://github.com" }); // 设置宽高 $('#qrcodeResize').qrcode({ width : 128, height : 128, text : "http://github.com" }); </ script > </ body > </ html > |
然后浏览器访问这个页面,就能看到 4 个二维码了。
注意一下:
- 总之,现在记下这篇文档的时候,按照官网和 github 还有其他一些博客上的说明都只加载了 jquery.qrcode.js (query.js 除外),但是只加载这一个 jQ 的话我这里行不通,必须再加载 qrcode.js
- jQ 生成 QR Code 的代码必需在容器元素后面,可以放在 <body> 标签内最后。如果放在<head>标签中也生不出来 QR Code。这是 github上的一个例子。
三、php 生成电子名片
1. vCard
vCard 是电子名片的文件格式标准。它一般附加在电子邮件之后,但也可以用于其它场合(如在互联网上相互交换)。vCard 可包含的信息有:姓名、地址资讯、电话号码、URL,logo,相片等(摘自维基百科)。
2. 样例
下面是一个包含个人信息的 vCard 格式电子名片(摘自维基百科),可以参照它来修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | BEGIN:VCARD VERSION:2.1 N:Gump;Forrest FN:Forrest Gump ORG:Gump Shrimp Co. TITLE:Shrimp Man TEL;WORK;VOICE:(111) 555-1212 TEL;HOME;VOICE:(404) 555-1212 ADR;WORK:;;100 Waters Edge;Baytown;LA;30314;United States of America LABEL;WORK;ENCODING=QUOTED-PRINTABLE:100 Waters Edge=0D=0ABaytown, LA 30314=0D=0AUnited States of America ADR;HOME:;;42 Plantation St.;Baytown;LA;30314;United States of America LABEL;HOME;ENCODING=QUOTED-PRINTABLE:42 Plantation St.=0D=0ABaytown, LA 30314=0D=0AUnited States of America EMAIL;PREF;INTERNET:forrestgump@walladalla.com REV:20080424T195243Z END:VCARD |
参考上面的 vCard 样例,可以制作个人的电子名片。具体的各个字段解释可以参考百度百科上的 vCard 介绍。
3. php 生成电子名片
照样子写一个,使用 phpqrcode 包来生成我的电子名片:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <?php // 使用 phpqrcode 生成电子名片 require './phpqrcode/qrlib.php' ; $vcard = <<<EOL BEGIN:VCARD VERSION:2.1 N:Jin;mingc FN:mingc ORG:free man TITLE:PHPer TEL;WORK;VOICE:1382173xxxx TEL;HOME;VOICE:1383284xxxx ADR;WORK;TianJin, China LABEL;WORK;ENCODING=QUOTED-PRINTABLE:TianJin, China(LABEL;WORK) ADR;HOME;TianJin, China LABEL;HOME;ENCODING=QUOTED-PRINTABLE:TianJin, China(LABEL;HOME) EMAIL;PREF;INTERNET:name@example.com REV:20171201T005548Z END :VCARD EOL; QRcode::png( $vcard ); // define('EOL', "\r\n"); // $vcard = 'BEGIN:VCARD'.EOL; // $vcard .= 'VERSION:2.1'.EOL; // $vcard .= 'N:Jin;mingc'.EOL; // $vcard .= 'FN:mingc'.EOL; // $vcard .= 'ORG:free man'.EOL; // $vcard .= 'TITLE:PHPer'.EOL; // $vcard .= 'TEL;WORK;VOICE:1382173xxxx'.EOL; // $vcard .= 'TEL;HOME;VOICE:1383284xxxx'.EOL; // $vcard .= 'ADR;WORK;TianJin, China'.EOL; // $vcard .= 'LABEL;WORK;ENCODING=QUOTED-PRINTABLE:TianJin, China(LABEL;WORK)'.EOL; // $vcard .= 'ADR;HOME;TianJin, China'.EOL; // $vcard .= 'LABEL;HOME;ENCODING=QUOTED-PRINTABLE:TianJin, China(LABEL;HOME)'.EOL; // $vcard .= 'EMAIL;PREF;INTERNET:name@example.com'.EOL; // $vcard .= 'REV:20171201T005548Z'.EOL; // $vcard .= 'END:VCARD'; // QRcode::png($vcard); |
浏览器访问这个 php 脚本会显示一张二维码,微信扫一扫,结果如下:
这个电子名片还可以直接添加到你的手机联系人里。
四、php 识别二维码(工具)
php 识别二维码或条形码需要 3 个工具。
1. ImageMagick
ImageMagick 是一个用于查看、编辑位图文件以及进行图像格式转换的开放源代码软件套装。它可以读取、编辑超过 100 种图象格式。ImageMagick 以 ImageMagick 许可证(一个类似 BSD 的许可证)发布。
2. zbar
zbar 是一个开源软件套件,用于读取各种来源的条形码,如视频流,图像文件和原始强度传感器。它支持 包括 EAN-13 / UPC-A,UPC-E,EAN-8,Code 128,Code 39,Interleaved 2 of 5 和 QR Code 等多种流行的条码。
3. php-zbarcode
php-zbarcode 是 PHP 读取条形码的扩展模块,目前仅支持 php5.x。使用这个模块之前还需要安装 ImageMagick 和 zbar 这两个命令行套件。
phpzbarcode 依赖于 ImageMagick 和 zbar,zbar 依赖于 ImageMagick,ImageMagick 依赖 jpeg 库来提供 jpeg 图片支持,所以先安装 jpeg 支持。
安装 jpeg 库
下载地址:http://www.imagemagick.org/download/delegates/,我下载的包名为 jpegsrc.v9b.tar.gz 。
1 2 3 4 5 6 | wget http: //www .imagemagick.org /download/delegates/jpegsrc .v9b. tar .gz tar xf jpegsrc.v9b. tar .gz cd jpeg-9b/ . /configure make sudo make install |
五、安装 ImageMagick
下载地址:https://www.imagemagick.org/download/,我下载的包名为 ImageMagick.tar.gz 。
1 2 3 4 5 6 7 8 | wget https: //www .imagemagick.org /download/ImageMagick . tar .gz tar xf ImageMagick. tar .gz cd ImageMagick-7.0.7-13 . /configure make sudo make install sudo ldconfig /usr/local/lib magick --version |
********************************************* 常见错误 *******************************************
出错1:安装好以后使用 magick 、 convert 等相关命令时,加载动态链接库出错
1 | convert: error while loading shared libraries: libMagickCore-7.Q16HDRI.so.4: cannot open shared object file : No such file or directory |
解决方法:设置动态加载动态链接库
1 | sudo ldconfig /usr/local/lib |
然后就可以正常使用命令行接口了。
六、安装 zbar
下载地址:https://sourceforge.net/projects/zbar/files/zbar/。我下载的最新版 0.10,包名为 zbar-0.10.tar.gz 。
1 2 3 4 5 6 7 8 9 | tar xf zbar-0.10. tar .gz cd zbar-0.10/ sudo ln -s /usr/local/include/ImageMagick-7 /usr/local/include/ImageMagick sudo ln -s /usr/local/include/ImageMagick-7/MagickWand /usr/local/include/wand . /configure --disable-video --without-gtk --without-qt --without-python make make sudo make install zbarimg --version |
********************************************* 常见错误 ********************************************
出错1:找不到 MagickWand.h 头文件
1 2 3 | ImageMagick package found but wand /MagickWand .h not installed?! -this is a problem with your ImageMagick install , -please resolve the inconsistency and try again... |
解决方法:zbar 的配置文件 ./configure 在运行时会找不到 MagickWand.h,它在 /usr/local/include/ImageMagick-7/MagickWand 目录下,但是 ./configure 执行时会去 wand/ 目录找(找不到),所以需要做两个软连接让 ./configure 能找到 MagickWand.h 文件
1 2 | sudo ln -s /usr/local/include/ImageMagick-7 /usr/local/include/ImageMagick sudo ln -s /usr/local/include/ImageMagick-7/MagickWand /usr/local/include/wand |
出错2:make 编译期间多处 warning 和 error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | zbar /decoder/ean .c: In function ‘ean_part_end4’: zbar /decoder/ean .c:245:13: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!par == fwd) { ^~ zbar /decoder/ean .c:245:8: note: add parentheses around left hand side expression to silence this warning if (!par == fwd) { ^~~~ ( ) zbar /decoder/ean .c: In function ‘ean_part_end7’: zbar /decoder/ean .c:294:13: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!par == fwd) { ^~ zbar /decoder/ean .c:294:8: note: add parentheses around left hand side expression to silence this warning if (!par == fwd) { ^~~~ ( ) zbar /qrcode/qrdec .c: In function ‘qr_finder_quick_crossing_check’: zbar /qrcode/qrdec .c:1215:27: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!_img[_y0*_width+_x0]!=_v||!_img[_y1*_width+_x1]!=_v) return 1; ^~ zbar /qrcode/qrdec .c:1215:6: note: add parentheses around left hand side expression to silence this warning if (!_img[_y0*_width+_x0]!=_v||!_img[_y1*_width+_x1]!=_v) return 1; ^~~~~~~~~~~~~~~~~~~~~ ( ) zbar /qrcode/qrdec .c:1215:54: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!_img[_y0*_width+_x0]!=_v||!_img[_y1*_width+_x1]!=_v) return 1; ^~ zbar /qrcode/qrdec .c:1215:33: note: add parentheses around left hand side expression to silence this warning if (!_img[_y0*_width+_x0]!=_v||!_img[_y1*_width+_x1]!=_v) return 1; ^~~~~~~~~~~~~~~~~~~~~ ( ) zbar /qrcode/qrdec .c:1216:45: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!_img[(_y0+_y1>>1)*_width+(_x0+_x1>>1)]==_v) return -1; ^~ zbar /qrcode/qrdec .c:1216:6: note: add parentheses around left hand side expression to silence this warning if (!_img[(_y0+_y1>>1)*_width+(_x0+_x1>>1)]==_v) return -1; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ( ) zbar /qrcode/qrdec .c: In function ‘qr_finder_locate_crossing’: zbar /qrcode/qrdec .c:1257:33: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!_img[x0[1]*_width+x0[0]]!=_v) break ; ^~ zbar /qrcode/qrdec .c:1257:8: note: add parentheses around left hand side expression to silence this warning if (!_img[x0[1]*_width+x0[0]]!=_v) break ; ^~~~~~~~~~~~~~~~~~~~~~~~~ ( ) zbar /qrcode/qrdec .c:1269:33: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] if (!_img[x1[1]*_width+x1[0]]!=_v) break ; ^~ zbar /qrcode/qrdec .c:1269:8: note: add parentheses around left hand side expression to silence this warning if (!_img[x1[1]*_width+x1[0]]!=_v) break ; ^~~~~~~~~~~~~~~~~~~~~~~~~ ( ) zbar /jpeg .c: In function ‘_zbar_convert_jpeg_to_y’: zbar /jpeg .c:174:39: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types] cinfo->src->fill_input_buffer = fill_input_buffer; ^ |
解决方法:再次编译
七、安装 php-zbarcode
下载地址:https://github.com/mkoppanen/php-zbarcode
1 2 3 4 5 6 7 | wget https: //github.com/mkoppanen/php-zbarcode/archive/master.zip unzip master.zip cd php-zbarcode-master/ phpize ./configure --with-php-config=/usr/bin/php-config make sudo make install |
成功后会提示安装到的模块目录
1 | Installing shared extensions: /usr/lib/php/20131226/ |
确认模块的位置
1 2 3 4 5 6 | mingc@mingc-GE60-2PL:~ /Downloads/qrcode/php-zbarcode-master $ ls /usr/lib/php/20131226/ build dom.so gettext.so mcrypt.so mysqli.so pdo_mysql.so posix.so sockets.so tokenizer.so xmlwriter.so bz2.so exif.so iconv.so memcached.so mysqlnd.so pdo_odbc.so readline.so sqlite3.so wddx.so xsl.so calendar.so fileinfo.so igbinary.so memcache.so mysql.so pdo.so redis.so sysvmsg.so xmlreader.so zbarcode.so ctype.so ftp .so json.so mongo.so odbc.so pdo_sqlite.so shmop.so sysvsem.so xmlrpc.so zip.so dba.so gd.so mbstring.so msgpack.so opcache.so phar.so simplexml.so sysvshm.so xml.so |
可以看到有了 zbarcode.so 文件。然后启用 zbarcode 扩展,编辑 /etc/php/5.6/apache2/php.ini 文件
1 | sudo vim /etc/php/5 .6 /apache2/php .ini |
最后添加一行
重启 apache
1 | sudo /etc/init .d /apache2 restart |
这就好了,可以使用条形码扩展了。
注意 php -m 命令显示的是 php-cli 模式启用的扩展,要让 php-cli 模式也启用扩展的话,需要再编辑 cli 模式的配置文件。在 /etc/php/5.6/cli/php.ini 里,最后添加一行
然后就能使用 php -m 命令看到 zbarcode 模块了。
八、php 识别二维码
参照 github 上的 php-zbarcode 示例,识别一下我刚才生成的电子名片。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php /* Create new image object */ $image = new ZBarCodeImage( "./qrcode_vcard.png" ); /* Create a barcode scanner */ $scanner = new ZBarCodeScanner(); /* Scan the image */ $barcode = $scanner ->scan( $image ); /* Loop through possible barcodes */ if (! empty ( $barcode )) { foreach ( $barcode as $code ) { printf( "Found type %s barcode with data %s\n" , $code [ 'type' ], $code [ 'data' ]); } } |
识别结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Found type QR-Code barcode with data BEGIN:VCARD VERSION:2.1 N:Jin;mingc FN:mingc ORG: free man TITLE:PHPer TEL;WORK;VOICE:1382173xxxx TEL;HOME;VOICE:1383284xxxx ADR;WORK;TianJin, China LABEL;WORK;ENCODING=QUOTED-PRINTABLE:TianJin, China(LABEL;WORK) ADR;HOME;TianJin, China LABEL;HOME;ENCODING=QUOTED-PRINTABLE:TianJin, China(LABEL;HOME) EMAIL;PREF;INTERNET:name@example.com REV:20171201T005548Z END:VCARD |