193天前2020-04-17 14:29:43 |    抢沙发  197 
最新在做关于php生成二维码的功能,之前对php的图像处理函数用的很少不是很熟悉,所以折腾了一症子。本文不做算法的讨论,直接给出实现方法,对于有需求的同学拿着也快,对我来说也节省时间。

php

我这里直接先贴出函数,然后再说使用发放就手工哈,时间不多。

方法:

//获取二维码
public function get_qr(){
  //引入类库
  include 'phpqrcode.php'
  //二维码包的含字符串
  $data['code'] = 'https://www.32e.top';
  //二维码大小
  $data['matrixPointSize'] = '10';
  //二维码容错等级
  $data['errorCorrectionLevel'] = 'H';
  //二维码空白边缘大小
  $data['size'] = '1';
  //logo地址
  $data['logo'] = 'https://www.32e.top/logo.png';

  if (!empty($data['code'])) {
    //不保存文件,直接返回GD资源
    $QR = QRcode::png($data['code'], false, $data['errorCorrectionLevel'], $data['matrixPointSize'],$data['size'],false,true);

    if (!empty($data['logo'])) {
      //如果不进行logo圆角处理的话就直接用这句
      // $logo = imagecreatefromstring(file_get_contents($data['logo']));
      //对logo进行圆角处理
      $logo = $this->radius_img($data['logo']);
      $QR_width = imagesx($QR);//二维码图片宽度
      $QR_height = imagesy($QR);//二维码图片高度
      $logo_width = imagesx($logo);//logo图片宽度
      $logo_height = imagesy($logo);//logo图片高度
      $logo_qr_width = $QR_width / 3;
      $scale = $logo_width/$logo_qr_width;
      $logo_qr_height = $logo_height/$scale;
      $from_width = ($QR_width - $logo_qr_width) / 2;
      //重新组合图片并调整大小
      imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,
      $logo_qr_height, $logo_width, $logo_height);
    }
    Header("Content-type: image/png");
    //直接输出到浏览器
    ImagePng($QR);
    //关闭图片资源
    ImageDestroy($QR);
  }
}

/**
 *图片圆角处理
 * @param  string  $imgpath 源图片路径
 * @param  integer $radius  圆角半径长度默认为15,处理成圆型
 */
function radius_img($imgpath='', $radius = 15) {
  if (!empty($imgpath)) {
    $getimg = getimagesize($imgpath);
    $src_img = imagecreatefromstring(file_get_contents($imgpath));
    $w  = $getimg['0'];
    $h  = $getimg['1'];

    // $radius = $radius == 0 ? (min($w, $h) / 2) : $radius;
    $img = imagecreatetruecolor($w, $h);
    //这一句一定要有
    imagesavealpha($img, true);
    //拾取一个完全透明的颜色,最后一个参数127为全透明
    $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
    imagefill($img, 0, 0, $bg);
    $r = $radius; //圆 角半径
    for ($x = 0; $x < $w; $x++) {
        for ($y = 0; $y < $h; $y++) {
            $rgbColor = imagecolorat($src_img, $x, $y);
            if (($x >= $radius && $x <= ($w - $radius)) || ($y >= $radius && $y <= ($h - $radius))) {
                //不在四角的范围内,直接画
                imagesetpixel($img, $x, $y, $rgbColor);
            } else {
                //在四角的范围内选择画
                //上左
                $y_x = $r; //圆心X坐标
                $y_y = $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
                //上右
                $y_x = $w - $r; //圆心X坐标
                $y_y = $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
                //下左
                $y_x = $r; //圆心X坐标
                $y_y = $h - $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
                //下右
                $y_x = $w - $r; //圆心X坐标
                $y_y = $h - $r; //圆心Y坐标
                if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }
    }
    return $img;
  }else{
    return false;
  }
}
直接调用get_qr方法就能输出带圆角logo的二维码了。

这里我再讲一个如何直接输出为base64的字符串图片,方便通过API接口来获取图片。

方法:

//生成二维码API
public function qr_api(){
  $return_data = array(
    'success'=>false,
    'data'=>'',
    'width'=>0,
    'height'=>0
  );
  include 'phpqrcode.php'
  //二维码包的含字符串
  $data['code'] = 'https://www.32e.top';
  //二维码大小
  $data['matrixPointSize'] = '10';
  //二维码容错等级
  $data['errorCorrectionLevel'] = 'H';
  //二维码空白边缘大小
  $data['size'] = '1';
  //logo地址
  $data['logo'] = 'https://www.32e.top/logo.png';

  if (!empty($data['code'])) {
    $return_data['success'] = true;
    //不保存文件,直接返回GD资源
    $QR = QRcode::png($data['code'], false, $data['errorCorrectionLevel'], $data['matrixPointSize'],$data['size'],false,true);

    if (!empty($data['logo'])) {
      $logo = $this->radius_img($data['logo']);
      $QR_width = imagesx($QR);//二维码图片宽度
      $QR_height = imagesy($QR);//二维码图片高度
      $logo_width = imagesx($logo);//logo图片宽度
      $logo_height = imagesy($logo);//logo图片高度
      $logo_qr_width = $QR_width / 3;
      $scale = $logo_width/$logo_qr_width;
      $logo_qr_height = $logo_height/$scale;
      $from_width = ($QR_width - $logo_qr_width) / 2;
      //重新组合图片并调整大小
      imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,
      $logo_qr_height, $logo_width, $logo_height);
    }
    //开启缓冲区
    ob_start ();
    //imagepng展示出图片
    ImagePng($QR);
    $imageData = ob_get_contents ();
    ob_end_clean ();
    $size_info = getimagesizefromstring($imageData);
    $return_data['width'] = isset($size_info['0'])?$size_info['0']:'0';
    $return_data['height'] = isset($size_info['1'])?$size_info['1']:'0';
    //得到这个结果,可以直接用于前端的img标签显示
    $imageDataBase64 = "data:image/png;base64,". base64_encode ($imageData);
    $return_data['data'] = $imageDataBase64;
    header('content-type:application/json');
    echo json_encode($return_data);
  }
}

直接调用上面的qr_api就能返回json格式的图片数据了,方便前端调用。

这里再贴出一个php生成圆形头像的方法吧:

/**
 * 处理成圆图片,如果图片不是正方形就取最小边的圆半径,从左边开始剪切成圆形
 * @param  string $imgpath [description]
 * @return [type]          [description]
 */
function yuan_img($imgpath = '') {
  $ext     = pathinfo($imgpath);
  $src_img = null;
  switch ($ext['extension']) {
  case 'jpg':
    $src_img = imagecreatefromjpeg($imgpath);
    break;
  case 'png':
    $src_img = imagecreatefrompng($imgpath);
    break;
  }
  $wh  = getimagesize($imgpath);
  $w   = $wh[0];
  $h   = $wh[1];
  $w   = min($w, $h);
  $h   = $w;
  $img = imagecreatetruecolor($w, $h);
  //这一句一定要有
  imagesavealpha($img, true);
  //拾取一个完全透明的颜色,最后一个参数127为全透明
  $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
  imagefill($img, 0, 0, $bg);
  $r   = $w / 2; //圆半径
  $y_x = $r; //圆心X坐标
  $y_y = $r; //圆心Y坐标
  for ($x = 0; $x < $w; $x++) {
    for ($y = 0; $y < $h; $y++) {
      $rgbColor = imagecolorat($src_img, $x, $y);
      if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
        imagesetpixel($img, $x, $y, $rgbColor);
      }
    }
  }
  return $img;
}
header("content-type:image/png");
$imgg = yuan_img();
imagepng($imgg);
imagedestroy($imgg);
方法来自网络,以为时间比较紧,且我目前也没有这个需求,所以就没有对这个函数进行改造,如果你要使用,可以参考上面我写的两个方法去进行对照修改一下就OK了。

需要注意的是,本文使用的phpqrcode二维码类库是进过本人修改过的类库,原生类库应该会报错,修改方法可以参考本站的另外一篇文章:PHP QR Code二维码生成插件类库二次开发扩展修改实现无存储直接返回图片资源对象,从而实现图片无存储对二维码的再次编辑


发表评论

暂无评论

登录

忘记密码 ?

切换登录

注册

扫一扫二维码分享