保留输出到前端、写入文件,去掉了写入文件同时输出到前端,增加贴Logo并且可以设置横向比例,增加返回GdImage对象可直接用于海报生成等场景,完善了jpg格式的输出。

调用示例 :

$logoUri='./path/to/logo.png'; //支持本地和网络资源,如需支持其他图片格式需要在相应位置作调整
$qr=new QRcode('这里是二维码内容');
$qr->png(NULL,$logoUri,20); //第一个参数是要写入的文件名(不含后缀),第三个参数是logo宽占二维码宽的比例
exit;

注意事项:

  • 如果可以,请使用PHP8,否则请删掉png和jpg方法的返回值类型约束
  • 建议PHP7以上,否则你将不能在png和jpg方法中使用??运算,需要改成三目运算
  • 实例化对象时只有一个必要参数$text-二维码内容
  • 获得结果的方法有三个:image、png、jpg
  • image方法返回GdImage对象,可以直接用于GD库生成海报等场景
  • png和jpg方法通过类的path属性和方法的filename参数区分输出到前端还是写入文件
  • 只有当path为空字符串且filename为NULL时才会输出到前端
  • filename不要传入空字符串,除非你想用空字符串取代NULL判断是否需要写入文件,这样的话你将不能使用??运算
  • 否则都会写入文件并返回文件名
  • 如果filename为NULL,将用微秒时间戳代替之;filename不要后缀(传了也没用)
  • 然后会把path属性和filename拼接起来并补上后缀,将数据写入文件
  • 需要注意的是,此时的返回值是完整路径而非文件名

使用方法:找到phpqrcode.php源码,删除QRcode、QRencode和QRtools三个类,替换为下面的带码段。
当然如果你愿意支持一下博主,也可以直接去用C币下载成品:面向对象风格的phpqrcode

class QRcode {private bool $casesensitive = true;private bool $eightbit = false;private int $hint = QR_MODE_8;private int $size; //设置单点像素数private int $margin; //设置边框点数private int $level; //设置纠错等级,1/2/3/4private string $path=''; //设置写入文件夹,空字符串时不写入private string $text; //设置内容private $version = 0;public int $points; //结果横边点数public int $w; //结果像素宽public int $h; //结果像素高public $data;public function __construct(string $text,int $level=1,int $size=5,int $margin=4,string $path=''){$this->setLevel($level);$this->setText($text); //setText应当在setLevel之后调用,否则$level属性不会生效$this->setSize($size);$this->setMargin($margin);$this->setPath($path);}public function image(string $logo=NULL,int $ratio=5) : \GdImage{$h = count($this->data);$w = strlen($this->data[0]);$imgW = $w + 2*$this->margin;$imgH = $h + 2*$this->margin;$base =ImageCreate($imgW, $imgH);$col[0] = ImageColorAllocate($base,255,255,255);$col[1] = ImageColorAllocate($base,0,0,0);imagefill($base, 0, 0, $col[0]);for($y=0; $y<$h; $y++) {for($x=0; $x<$w; $x++) {if($this->data[$y][$x]=='1') ImageSetPixel($base,$x+$this->margin,$y+$this->margin,$col[1]);}}$pixelPerPoint=min($this->size,intval(QR_PNG_MAXIMUM_SIZE/(count($this->data)+2*$this->margin)));$this->w=$imgW*$pixelPerPoint;$this->h=$imgH*$pixelPerPoint;$target=ImageCreate($this->w,$this->h);ImageCopyResized($target,$base,0,0,0,0,$this->w,$this->h,$imgW,$imgH);ImageDestroy($base);if(isset($logo)&&$ratio>1&&file_exists($logo)){// 因为可以用透明色使边角圆润,所以我的logo都是PNG格式的,因此这里就懒得判断了,如果想支持其他格式可以在这里判断文件类型$lg=imagecreatefrompng($logo);// 一般情况下二维码和logo都是正方形的,但为保证兼容和美观,这里只有宽度是按输入比例调整的,高度则是根据logo原比例自适应$lgSize=getimagesize($logo);$lgW=(int)round($this->w*$ratio/100);$lgH=$lgSize[1]*$lgW/$lgSize[0];imagecopyresampled($target,$lg,intval(($this->w-$lgW)/2),intval(($this->h-$lgH)/2),0,0,$lgW,$lgH,$lgSize[0],$lgSize[1]);}return $target;}/*下面两个方法用到了php8的联合类型约束,不重要,低版本删掉约束即可*/public function png(string $filename = NULL,string $logo=NULL,int $ratio=20) : NULL|string{$resource=$this->image($logo,$ratio);if($this->path===''&&!isset($filename)) Header("Content-type: image/png");else $filename=$this->path.($filename??microtime(TRUE)).'.png';ImagePng($resource,$filename);ImageDestroy($resource);$resource=NULL;return $filename;}public function jpg(int $q=85,string $filename = NULL,string $logo=NULL,int $ratio=20) : NULL|string{$resource=$this->image($logo,$ratio);if($this->path===''&&!isset($filename)) Header("Content-type: image/jpeg");else $filename=$this->path.($filename??microtime(TRUE)).'.jpeg';ImageJpeg($resource, $filename, $q);ImageDestroy($resource);$resource=NULL;return $filename;}public function setText(string $text) : self{$input = new QRinput($this->version, $this->level);if($input == NULL) return $this;if($this->eightbit) {if($text == NULL) throw new \Exception('empty string!');$ret = $input->append($input,QR_MODE_8,strlen($text),str_split($text));} else {if($this->hint!==QR_MODE_8&&$this->hint!=QR_MODE_KANJI) throw new \Exception('bad hint');$ret = QRsplit::splitStringToQRinput($text,$input,$this->hint,$this->casesensitive);}if($ret<0){unset($input);return $this;}$mask=-1;if($input->getVersion()<0||$input->getVersion()>QRSPEC_VERSION_MAX) throw new \Exception('wrong version');if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) throw new \Exception('wrong level');$raw = new QRrawcode($input);$version = $raw->version;$width = QRspec::getWidth($version);$frame = QRspec::newFrame($version);$filler = new FrameFiller($width, $frame);if(is_null($filler)) {return $this;}// inteleaved data and ecc codesfor($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) {$code = $raw->getCode();$bit = 0x80;for($j=0; $j<8; $j++) {$addr = $filler->next();$filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));$bit = $bit >> 1;}}unset($raw);// remainder bits$j = QRspec::getRemainder($version);for($i=0; $i<$j; $i++) {$addr = $filler->next();$filler->setFrameAt($addr, 0x02);}$frame = $filler->frame;unset($filler);// masking$maskObj = new QRmask();if($mask < 0) {if (QR_FIND_BEST_MASK) {$masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());} else {$masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());}} else {$masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());}if($masked == NULL) return $this;// 原本有个raw方法,返回的是此时的$masked值$this->version = $version;$this->points = $width;$len = count($masked);foreach ($masked as &$frameLine) {for($i=0; $i<$len; $i++) {$frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';}}// 原本有个text方法,传入$text和$outfile参数// 如果$outfile值有效,返回值是这里的$masked值// 否则则写入文件file_put_contents($outfile,join("\n",$masked));// 现在$text已经拆到setText方法中了$this->data = $masked;return $this;}public function setPath(string $path) : self{if($this->path===$path) return $this;if(!file_exists($path)) mkdir($path,0777,TRUE);$this->path=$path;return $this;}public function setLevel(int $level) : self{if($level<QR_ECLEVEL_L) $this->level=QR_ECLEVEL_L;elseif($level>QR_ECLEVEL_H) $this->level=QR_ECLEVEL_H;else $this->level=$level;return $this;}public function setSize(int $size) : self{$this->size=$size>1?$size:1;return $this;}public function setMargin(int $margin) : self{$this->margin=$margin>0?($margin<10?$margin:10):0;return $this;}
}

PHP二维码类库phpqrcode改造面向对象风格相关推荐

  1. 二维码类库--phpqrcode使用简介

    #载入类文件 include 'phpqrcode.php'; $value = '二维码内容'; $errorCorrectionLevel = 'L';//容错级别 L.M.Q.H $matrix ...

  2. 二维码太丑?用风格迁移生成个性二维码了解一下

    文章选自arXiv,作者:Mingliang Xu等,机器之心编译 手机二维码太普通,换来换去还是不好看.何不自定义一个自己喜欢的呢?近日,郑州大学.浙江大学.微软亚洲研究院.北京航空航天大学的研究者 ...

  3. thinkphp 使用phpqrcode生成带logo二维码 并生成海报

    1-下载类库 composer require aferrandini/phpqrcode -vvv 2-common的方法 //$text 文本的内容 //$logo logo图片 function ...

  4. 使用phpqrcode生成带logo二维码 并生成海报

    1-下载类库 composer require aferrandini/phpqrcode -vvv 2-common的方法 //$text 文本的内容 //$logo logo图片 function ...

  5. php phpqrcode 生成二维码

    <?php // ==============php phpqrcode 生成二维码======================== // 下载地址:http://sourceforge.net ...

  6. 基于SignalR的消息推送与二维码描登录实现

    1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于Singl ...

  7. qrcode-php生成二维码

    调用PHP QR Code非常简单,如下代码即可生成一张内容为"http://www.baidu.com"的二维码. include 'phpqrcode.php'; QRcode ...

  8. 聊聊 Web 项目二维码生成的最佳姿势

    在设计和实现的过程之后,你永远不知道部署上去的程序会已什么样的姿势运行. 本篇借一次生成二维码逻辑的不同实现,阐述 Web 项目中二维码生成的正确姿势. 文中如有批量,欢迎各位看客老爷拍砖.试运行前5 ...

  9. 微信开发——带参数二维码的使用

    最近做微信PC端网页微信相关功能的开发,从一个新手的角度来说,微信公众号的文档还是不好理解的,网上找的帖子大都也都基本上是复制微信公众平台上给的文档,开发微信带参数二维码过程中还是遇到不少坑的,在此把 ...

最新文章

  1. VMWare中CentOS7 设置固定IP且能够访问外网
  2. 本地化,将cancel替换成取消
  3. python 目录和文件操作
  4. debian下为python2.7 安装MySQLdb扩展(mariadb)
  5. 百步斋诗钞【绝句四首】
  6. what you should do if you want to exercise?
  7. Linux学习:shell 命令(用户管理)
  8. 申请评分卡(A卡)的开发过程(1)
  9. qt5 linux 窗口不能置顶_Qt 5.15 LTS发布,Qt 6要来了
  10. docker 安装镜像失败_docker(mips 64)安装中文字符集失败
  11. List vs IEnumerable vs IQueryable vs ICollection vs IDictionary
  12. tablix“Tablix1”有一个具有内部成员的详细信息成员
  13. ssas连接mysql_BI-SSAS简介篇
  14. ContextCapture(CC)/Smart3D集群搭建笔记
  15. BaseTestCase system 1.0 体验版
  16. String字符串拼接原理
  17. 计算机编程 计算存款利息,作业报告12 定期存款利息计算器
  18. 【聚划算 Android 技术周刊 第五期- 20160912】
  19. 西门子消防主机FC18配套CAN光端机进行光纤冗余环网组网测试
  20. 【软件安装】结合树莓派4B(4G)和Ubuntu20.04的GitLab服务器搭建和使用

热门文章

  1. 【前端学习记录1】HTML简介和开发工具
  2. resteasy 注解操作
  3. Web3中文|随着世界杯结束,web3体育可能达到800亿美元
  4. 王者系统不能连上聊天服务器,《王者荣耀》同城频道不能发言聊天原因 同城为什么不能发言...
  5. 用c语言怎么求最大公约数,c语言求最大公约数
  6. Re-ID数据集介绍
  7. python简单练习题
  8. 计算机企业锻炼总结,计算机教师企业锻炼总结汇报2021【5篇】.docx
  9. python中的utils模块_python学习笔记-import utils报错
  10. java.lang.NullPointerException: Attempt to read from field ‘android.widget.TextView com.example.demo