前言:

  对于小程序大家可能都非常熟悉了,随着小程序的不断普及越来越多的公司都开始推广使用起来了。今天接到一个需求就是生成小程序码,并且于运营给的推广图片合并在一起做成一张漂亮美观的推广二维码,扫码这种二维码就可以进入小程序。为了节省服务器内存资源,我想的就是成功调用通微信生成小程序码的接口后直接把微信返回过来的图片二进制内容(返回的图片 Buffer)转化为二进制byte[]文件流,然后再转成Image这样就不需要在保存到本地直接读取本地的背景图片通过GDI+(Graphics)绘制图片。废话不多说直接上码,各位同学假如有什么小程序的开发问题都欢迎评论区,或者qq私聊我有时间都可以一起学习探索。

选择小程序码生成方式:

首先微信小程序官方文档提供了三种生成小程序码的方法,如下所示(本文采用的是第三种,需要的码数量极多的业务场景):

文档详情地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html

1、createwxaqrcode获取小程序二维码,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制。

2、getwxacode获取小程序码,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制。

3、getwxacodeunlimit获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。

获取小程序全局唯一后台接口调用凭据(access_token):

  对接开发过微信相关的业务的同学应该都清楚,调用微信接口很多情况下都会需要使用到access_token接口调用凭证。一般来说access_token的有效时长为2小时,为了不频繁调用该接口我们可以通过缓存的方法把调用凭证存起来并设置合理的过期时间(redis,cookie,memorycache都是非常不错的选择)。

请求地址:

GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

请求参数:

属性 类型 默认值 必填 说明
grant_type string   填写 client_credential
appid string   小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态)
secret string   小程序唯一凭证密钥,即 AppSecret,获取方式同 appid

返回值(JSON 数据包):

属性 类型 说明
access_token string 获取到的凭证
expires_in number 凭证有效时间,单位:秒。目前是7200秒之内的值。
errcode number 错误码
errmsg string 错误信息

请求代码:

/// <summary>
/// 获取小程序全局唯一后台接口调用凭据(access_token)
/// </summary>
/// <returns></returns>
public string GetWechatAccessToken()
{
var appId = "你的小程序AppID";//小程序唯一凭证,即 AppID
var secret = "你的小程序AppSecret"; //小程序唯一凭证密钥,即 AppSecret
string Url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, secret); string Result = HttpWebRequest(Url, "GET", "", Encoding.UTF8); var obj = JsonConvert.DeserializeObject<AccessToken>(Result); if (obj != null && obj.access_token != null)
{
return obj.access_token;
}
else
{
return "";
}
} /// <summary>
/// WebRequest网络请求
/// </summary>
/// <param name="requestUrl">请求地址</param>
/// <param name="method">请求方式(GET/POST)</param>
/// <param name="data">请求参数(method="POST"需要携带)</param>
/// <param name="encoding">字符编码</param>
/// <param name="contentType">请求数据的内容类型</param>
/// <returns></returns>
public string HttpWebRequest(string requestUrl, string method, string data, Encoding encoding,string contentType="application/json;charset=UTF-8")
{
WebRequest webRequest = WebRequest.Create(requestUrl);
webRequest.Method = method;
if (method == "POST")
{
byte[] bytes = Encoding.Default.GetBytes(data);
webRequest.ContentType = contentType;
webRequest.ContentLength = bytes.Length;
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
} WebResponse response = webRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
if (responseStream == null)
{
return "";
} StreamReader streamReader = new StreamReader(responseStream, encoding);
string result = streamReader.ReadToEnd();
responseStream.Close();
streamReader.Close();
return result;
} /// <summary>
/// 响应模型
/// </summary>
public class AccessToken
{
/// <summary>
/// 获取到的凭证
/// </summary>
public string access_token { get; set; } /// <summary>
/// 凭证有效时间,单位:秒。目前是7200秒之内的值
/// </summary>
public int expires_in { get; set; } /// <summary>
/// 错误码
/// </summary>
public int errcode { get; set; } /// <summary>
/// 错误信息
/// </summary>
public string errmsg { get; set; }
}

小程序码获取:

请求地址:

POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN

请求参数

属性 类型 默认值 必填 说明
access_token string   接口调用凭证
scene string   最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
page string 主页 必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
width number 430 二维码的宽度,单位 px,最小 280px,最大 1280px
auto_color boolean false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false
line_color Object {"r":0,"g":0,"b":0} auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
is_hyaline boolean false 是否需要透明底色,为 true 时,生成透明底色的小程序

请求成功返回值:

返回的图片 Buffer(如果调用成功,会直接返回图片二进制内容(图片文件流),如果请求失败,会返回 JSON 格式的数据。)

请求异常返回值:

属性 类型 说明
errcode number 错误码
errmsg string 错误信息

请求代码:

注意:这个与前面获取授权凭证的网络请求不同的是因为要接收请求返回过来的图片二进制内容(buffer),然后需要把二进制文件流转化为byte[]二进制字节流,然后在转化Image。

        /// <summary>
/// 获取小程序码图片
/// </summary>
/// <param name="access_token">接口调用凭据</param>
/// <param name="param">携带参数</param>
private Image GetWetchatAppletQRCodeImage(string access_token, string param)
{
string requestData = "{\"scene\":\"" + param + "\"}";
string requestUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = "POST";
request.ContentType = "application/json;charset=UTF-8";
byte[] payload = System.Text.Encoding.UTF8.GetBytes(requestData);
request.ContentLength = payload.Length;
Stream writer = request.GetRequestStream();
writer.Write(payload, 0, payload.Length);
writer.Close();
HttpWebResponse response;
response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();//获取返回的图片 Buffer(文件流)
byte[] imageBuffer = StreamToBytes(stream); return ByteArrayConvertToImage(imageBuffer);
} /// <summary>
/// 将文件数据流转为二进制byte[]字节流
/// </summary>
/// <param name="stream">文件流</param>
/// <returns></returns>
private byte[] StreamToBytes(Stream stream)
{
List<byte> bytes = new List<byte>();
int temp = stream.ReadByte();
while (temp != -1)
{
bytes.Add((byte)temp);
temp = stream.ReadByte();
}
return bytes.ToArray();
} /// <summary>
/// byte [] 转化为Iamge
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public static Image ByteArrayConvertToImage(byte[] buffer)
{
using (MemoryStream ms = new MemoryStream(buffer))
{
// 直接调用Image库类中自带的方法使用MemoryStream实例对象获取Image
return Image.FromStream(ms);
}
}

小程序码和背景图合并:

        /// <summary>
/// 小程序推广二维码获取
/// </summary>
/// <param name="userId">小程序码携带的用户参数</param>
/// <returns></returns>
public JsonResult GetCompositePictureUrl(int userId)
{
//图片存放物理路径
var savePhysicalPath = HttpContext.Request.MapPath("~/qrcode/"); var imgBack = Image.FromFile(savePhysicalPath + "ewm.jpg");//合成背景图片
var wechatQrcodeImg = GetWetchatAppletQRCodeImage(GetWechatAccessToken(),userId.ToString());//获取小程序码图片
var compositePictureUrl = CompositePicture(imgBack, wechatQrcodeImg, savePhysicalPath, 232, 719, 290, 290); return Json(new { code = 0, compositePictureUrl = compositePictureUrl });
} /// <summary>
/// 合成图片
/// </summary>
/// <param name="backgroundImage">背景图</param>
/// <param name="qrCodeImg">二维码图片</param>
/// <param name="savePhysicalPath">图片存放物理路径</param>
/// <param name="xDeviation">绘制图像X轴偏差</param>
/// <param name="yDeviation">绘制图像Y轴偏差</param>
/// <param name="width">绘制图像宽</param>
/// <param name="height">绘制图像高</param>
/// <returns></returns>
public string CompositePicture(Image backgroundImage, Image qrCodeImg, string savePhysicalPath, int xDeviation = 0, int yDeviation = 0, int width = 0, int height = 0)
{
Bitmap bitmap = new Bitmap(backgroundImage.Width, backgroundImage.Height);
Graphics graphics = Graphics.FromImage(bitmap);//绘图
graphics.Clear(Color.White);
SolidBrush surush = new SolidBrush(Color.White);
graphics.DrawImage(backgroundImage, 0, 0, backgroundImage.Width, backgroundImage.Height);
graphics.DrawImage(qrCodeImg, xDeviation, yDeviation, width, height);
GC.Collect();//垃圾清理 string compositePictureUrl = savePhysicalPath + Guid.NewGuid().ToString() + ".jpg";
//合成图片保存
bitmap.Save(compositePictureUrl, System.Drawing.Imaging.ImageFormat.Jpeg); return compositePictureUrl;
}

合成效果图:

.NET生成小程序码,并合自定义背景图生成推广小程序二维码的更多相关文章

  1. qrcodenet二维码图片下扩展区域添加号段的操作

    总监安排了个任务,一个号码导出一个二维码图, 我实现了最终还能批量生成,结果主管说要在图片下边添加一行,和图片是一起的 最开始把控件的上的图给改了,结果保存起来没用,控件上的图跟要保存的不是一个事. ...

  2. 一次CTF后对二维码的认识

    前一段时间参加一个CTF比赛的时候其中有一个题目就是一张二维码图片,然后获取其中的信息来解题,那个二维码的特别之处在于,它把3个位置探测区域用几张美女图片代替了,然后在做题的时候顺便简单的了解了一下二 ...

  3. uniapp 微信小程序 生成二维码

    使用 tki-qrcode组件 生成二维码(https://www.npmjs.com/package/tki-qrcode) 1.引入 tki-qrcode 下载组件后引入 import tkiQr ...

  4. 微信小程序与内嵌webview之间来回跳转的几点总结,以及二维码的使用

    截止到发稿小程序支持的功能,后续如果小程序更新在完善文稿. 1. 小程序可以内嵌组件跳转到h5页面,前提是在小程序后台配置相应的业务域名.新打开的h5页面会替代小程序组件内的其它组件,即为h5不能与小 ...

  5. 微信小程序二维码推广统计

    微信小程序可以通过生成带参数的二维码,那么这个参数是可以通过APP的页面进行监控的 这样就可以统计每个二维码的推广效果. 今天由好推二维码推出的小程序统计工具HotApp小程序统计也推出了带参数二维码 ...

  6. 小程序入口构造工具&二维码测试工具

    小程序入口构造工具&二维码测试工具 本文将介绍我们小程序中隐藏的两个工具页面.原理虽不复杂,收益却实实在在,或许也能给诸君带来启发. 入口构造工具 痛点 PM&运营 投放链接 PM&a ...

  7. jquery-qrcode客户端二维码生成类库扩展--融入自定义Logo图片

    年后换了部门,现在主要的职责就是在网上卖精油,似乎这个就是传说中的网络营销. 跟着公司的MM们也了解不了少关于网络营销的知识,间接的了解到马云和刘强东都是些怎样龌龊的人,尽管之前也这样认为. 淘宝就不 ...

  8. 【Win】Clso QR Tool 二维码小工具

    一个可以生成并识别二维码的windows小工具,纯绿色.不含糖. 可以通过输入文本生成二维码,或者加载本地图片.剪贴板内的图片,直接解析出二维码内容. 支持自定义LOGO. 下载文件 (当前版本:1. ...

  9. python笔记 利用python 自动生成条形码 二维码

    1. ean13标准条形码 from pystrich.ean13 import EAN13Encoder encode = EAN13Encoder(') encode.save('d:/barco ...

随机推荐

  1. ASP.NET Core扩展库之实体映射

    在分层设计模式中,各层之间的数据通常通过数据传输对象(DTO)来进行数据的传递,而大多数情况下,各层数据的定义结构大同小异,如何在这些定义结构中相互转换,之前我们通过使用AutoMapper库,但Au ...

  2. sqlmap在https下的一种错误 - ssl连接失败

    在昨天与师傅的交流中师傅考了我一个问题,在用sqlmap跑的时候遇到ssl爆红该怎么办,因为在实战中并没有遇到过这种情况,所以今天补一下知识. 首先查询了ssl的概念,通俗来说,如果一个网站没有安装s ...

  3. Visual Studio添加引用的方式

  4. Apache JMeter 5.4.1 Build Development

                    1. 说明 经过漫长的等待终于将开发环境搭建成功了!网络慢真的是伤不起!grade,确实要比maven简洁.....嗯!真香! 2. 工具准备 JDK1.8+ 这... ...

  5. 庐山真面目之十四微服务架构的Docker虚拟技术深入探究

    庐山真面目之十四微服务架构的Docker虚拟技术深入探究 一.我的开场白 曾几何时,分布式的发展也影响了后来的微服务架构的实现方式.到了现在,只要涉及到互联网技术领域,就会设计一个概念,那就是微服务. ...

  6. 前端富文本编辑器vue + tinymce

    之前有项目需要用到富文本编辑器,在网上找了好几个后,最终选择了这个功能强大,扩展性强的tinymce tinymce中文文档地址(不全):http://tinymce.ax-z.cn/ tinymce ...

  7. Java 获取Word中的标题大纲(目录)

    概述 Word中的标题可通过"样式"中的选项来快速设置(如图1), 图1 在添加目录时,可将"有效样式"设置为"目录级别"显示(如图2),一 ...

  8. 如何调试 Java 开源项目源码,记一种源码导入开发工具并调试的通用方法

    楔子 说起读开源项目源码,很多朋友觉得高大上.大佬牛逼,云云~ 挡在很多人面前的不是源码怎么读,而是不知道如何导入源码到开发工具以及如何调试源码. 本文将以 spring-cloud-gateway ...

  9. 机器学习--如何理解Accuracy, Precision, Recall, F1 score

    当我们在谈论一个模型好坏的时候,我们常常会听到准确率(Accuracy)这个词,我们也会听到"如何才能使模型的Accurcy更高".那么是不是准确率最高的模型就一定是最好的模型? 这篇博文会向大家解释 ...

  10. C#与Python交互方式

    前言: 在平时工作中,需求有多种实现方式:根据不同的需求可以采用不同的编程语言来实现.发挥各种语言的强项 如:Python的强项是:数据分析.人工智能等 .NET 开发桌面程序界面比Python更简单 ...