.NET生成微信小程序推广二维码

2025-12-13 0 692

前言

对于小程序大家可能都非常熟悉了,随着小程序的不断普及越来越多的公司都开始推广使用起来了。今天接到一个需求就是生成小程序码,并且与运营给的推广图片合并在一起做成一张漂亮美观的推广二维码,扫码这种二维码就可以进入小程序。为了节省服务器内存资源,我想的就是成功调用通微信生成小程序码的接口后直接把微信返回过来的图片二进制内容(返回的图片 Buffer)转化为二进制byte[]文件流,然后再转成Image这样就不需要在保存到本地直接读取本地的背景图片通过GDI+(Graphics)绘制图片。

选择小程序码生成方式

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

文档详情地址:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getQRCode.html

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

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

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

获取全局唯一后台接口调用凭据

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

文档详情地址:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html

请求接口

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

返回参数

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

access_token 的存储与更新

  • access_token的存储至少要保留 512 个字符空间;
  • access_token的有效期目前为2 个小时,需定时刷新,重复获取将导致上次获取的access_token失效;
  • 建议开发者使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;
  • access_token的有效期通过返回的expires_in来传达,目前是7200秒之内的值,中控服务器需要根据这个有效时间提前去刷新。在刷新过程中,中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,新老access_token都可用,这保证了第三方业务的平滑过渡;
  • access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。

详情可参考微信公众平台文档《获取access_token》

请求示例代码

/// <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 接口调用凭证,该参数为 URL 参数,非 Body 参数。使用getAccessToken或者authorizer_access_token
scene string 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&\'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
page string 默认是主页,页面 page,例如 pages/index/index,根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面。scancode_time为系统保留参数,不允许配置
check_path bool 默认是true,检查page 是否存在,为 true 时 page 必须是已经发布的小程序存在的页面(否则报错);为 false 时允许小程序未发布或者 page 不存在, 但page 有数量上限(60000个)请勿滥用。
env_version string 要打开的小程序版本。正式版为 \”release\”,体验版为 \”trial\”,开发版为 \”develop\”。默认是正式版。
width number 默认430,二维码的宽度,单位 px,最小 280px,最大 1280px
auto_color bool 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false
line_color object 默认是{\”r\”:0,\”g\”:0,\”b\”:0} 。auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {\”r\”:\”xxx\”,\”g\”:\”xxx\”,\”b\”:\”xxx\”} 十进制表示
is_hyaline bool 默认是false,是否需要透明底色,为 true 时,生成透明底色的小程序

返回参数

属性 类型 说明
buffer buffer 图片 Buffer
errcode number 错误码
errmsg string 错误信息

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

请求代码

注意:这个与前面获取授权凭证的网络请求不同的是因为要接收请求返回过来的图片二进制内容(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生成微信小程序推广二维码

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 .NET生成微信小程序推广二维码 https://www.zuozi.net/36515.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务