生成底部带编号的二维码如下图所示:
具体实现代码如下:
<?php namespace App\Http\Controllers\Api; use App\Models\OrderGoods; use Illuminate\Foundation\Application; use Illuminate\Http\Request; use App\Utils\CodeUtil; use App\Models\Order; use App\Services\Other\JSSDK; use Illuminate\Support\Facades\Artisan; class OrderController extends CommonController { public function test() { $product_sn = \'123456-1\'; $new_order_goods_id = 1; $qrcode = self::makeMergerImg($product_sn,$new_order_goods_id); } //生成带编号说明的二维码 (生成二维码 文字生成图片 图片合并拼接) public static function makeMergerImg($sn_product,$new_order_goods_id){ self::getQrcode($new_order_goods_id, \'pages/order-detail/order-detail\'); self::makeImgWithStr(\'upload/sn_str_img/\'.$sn_product.\'.jpg\',$sn_product,18); self::CompositeImage([\'upload/qrcode/qrcode_\'.$new_order_goods_id.\'.jpg\',\'upload/sn_str_img/\'.$sn_product.\'.jpg\'],\'upload/pin_code/\'.$sn_product.\'.jpg\',\'y\',\'jpg\'); unlink(\'upload/sn_str_img/\'.$sn_product.\'.jpg\'); return \'/upload/pin_code/\'.$sn_product.\'.jpg\'; } /** * 获取小程序二维码 * @param int $order_id 订单ID * @param varchar $samll_program_url 要跳转的路径(小程序路径) */ protected static function getQrcode($order_id, $samll_program_url) { $filename = "qrcode_" . $order_id . ".jpg";//要生成的图片名字 $base_path = base_path() . "/public"; $IMG_PATH = \'/upload/qrcode\';//保存服务器路径 $shop_url = config(\'app.url\');//网址 if (file_exists(\'.\' . $IMG_PATH . \'/\' . $filename)) { //存在返回图片路径 return $shop_url . $IMG_PATH . \'/\' . $filename; } $jssdk = new JSSDK(config(\'wechat.xcx_app_id\'), config(\'wechat.secret\')); $access_token = $jssdk->getAccessTokenMinProgram(); $scene = $order_id; $data = \'{"scene":"\' . $scene . \'","page":"\' . $samll_program_url . \'","width":280}\'; $jpg = self::posturl(\'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=\' . $access_token, $data);//二进制原始数据 $res = file_put_contents($base_path . $IMG_PATH . \'/\' . $filename, $jpg); return $IMG_PATH . \'/\' . $filename; } //文字生成图片 public static function makeImgWithStr($filename, $text, $font_size=16,$font = \'/font/Arial/Arial.ttf\') { //图片尺寸 $im = imagecreatetruecolor(280, 70); //背景色 $white = imagecolorallocate($im, 255, 255, 255); //字体颜色 $black = imagecolorallocate($im, 0, 0, 0); imagefilledrectangle($im, 0, 0, 280, 300, $white); $txt_max_width = intval(0.8 * 280); $content = ""; for ($i = 0; $i < mb_strlen($text); $i++) { $letter[] = mb_substr($text, $i, 1); } foreach ($letter as $l) { $test_str = $content . " " . $l; $test_box = imagettfbbox($font_size, 0, $font, $test_str); // 判断拼接后的字符串是否超过预设的宽度。超出宽度添加换行 if (($test_box[2] > $txt_max_width) && ($content !== "")) { $content .= "\n"; } $content .= $l; } $txt_width = $test_box[2] - $test_box[0]; $y = 70 * 0.5; // 文字从何处的高度开始 $x = (280 - $txt_width) / 2; //文字居中 // echo $x;die; //文字写入 imagettftext($im, $font_size, 0, $x, $y, $black, $font, $content); //写 TTF 文字到图中 //图片保存 imagejpeg($im, $filename); } /** * 合并图片,拼接合并 * @param array $image_path 需要合成的图片数组 * @param $save_path 合成后图片保存路径 * @param string $axis 合成方向 * @param string $save_type 合成后图片保存类型 * @return bool|array */ public static function CompositeImage(array $image_path, $save_path, $axis = \'y\', $save_type = \'png\') { if (count($image_path) < 2) { return false; } //定义一个图片对象数组 $image_obj = []; //获取图片信息 $width = 0; $height = 0; foreach ($image_path as $k => $v) { $pic_info = getimagesize($v); list($mime, $type) = explode(\'/\', $pic_info[\'mime\']); //获取宽高度 $width += $pic_info[0]; $height += $pic_info[1]; if ($type == \'jpeg\') { $image_obj[] = imagecreatefromjpeg($v); } elseif ($type == \'png\') { $image_obj[] = imagecreatefrompng($v); } else { $image_obj[] = imagecreatefromgif($v); } } //按轴生成画布方向 if ($axis == \'x\') { //TODO X轴无缝合成时请保证所有图片高度相同 $img = imageCreatetruecolor($width, imagesy($image_obj[0])); } else { //TODO Y轴无缝合成时请保证所有图片宽度相同 $img = imageCreatetruecolor(imagesx($image_obj[0]), $height); } //创建画布颜色 $color = imagecolorallocate($img, 255, 255, 255); imagefill($image_obj[0], 0, 0, $color); //创建画布 imageColorTransparent($img, $color); imagecopyresampled($img, $image_obj[0], 0, 0, 0, 0, imagesx($image_obj[0]), imagesy($image_obj[0]), imagesx($image_obj[0]), imagesy($image_obj[0])); $yx = imagesx($image_obj[0]); $x = 0; $yy = imagesy($image_obj[0]); $y = 0; //循环生成图片 for ($i = 1; $i <= count($image_obj) - 1; $i++) { if ($axis == \'x\') { $x = $x + $yx; imagecopymerge($img, $image_obj[$i], $x, 0, 0, 0, imagesx($image_obj[$i]), imagesy($image_obj[$i]), 100); } else { $y = $y + $yy; imagecopymerge($img, $image_obj[$i], 0, $y, 0, 0, imagesx($image_obj[$i]), imagesy($image_obj[$i]), 100); } } //设置合成后图片保存类型 if ($save_type == \'png\') { imagepng($img, $save_path); } elseif ($save_type == \'jpg\' || $save_type == \'jpeg\') { imagejpeg($img, $save_path); } else { imagegif($img, $save_path); } return true; } /* 图片等宽处理 */ public static function ImgCompress($src, $out_with = 150) { // 获取图片基本信息 list($width, $height, $type, $attr) = getimagesize($src); // 获取图片后缀名 $pic_type = image_type_to_extension($type, false); // 拼接方法 $imagecreatefrom = "imagecreatefrom" . $pic_type; // 打开传入的图片 $in_pic = $imagecreatefrom($src); // 压缩后的图片长宽 $new_width = $out_with; $new_height = $out_with / $width * $height; // 生成中间图片 $temp = imagecreatetruecolor($new_width, $new_height); // 图片按比例合并在一起。 imagecopyresampled($temp, $in_pic, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // 销毁输入图片 imagejpeg($temp, \'upload/merge\' . time() . ".jpg"); imagedestroy($in_pic); return array($temp, $new_width, $new_height); } public static function posturl($url, $data) { $headerArray = array("Content-type:application/json;charset=\'utf-8\'", "Accept:application/json"); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArray); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($curl); curl_close($curl); return $output; } }
请发表评论