最近在做一个物业管理系统,其中有个功能是后台生成设备巡检的二维码,物业员工在小程序中扫码完成巡检任务
这里将这个功能记录下,挺简单的
1、创建QRCoderHelper类,用于生成二维码,这里需要引用QRCoder,使用vs自带的Nuget下载安装即可
using QRCoder;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Web;
namespace Application.Web.Common
{
public class QRCoderHelper
{
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="msg">信息</param>
/// <param name="version">版本 1 ~ 40</param>
/// <param name="pixel">像素点大小</param>
/// <param name="icon_path">图标路径</param>
/// <param name="icon_size">图标尺寸</param>
/// <param name="icon_border">图标边框厚度</param>
/// <param name="white_edge">二维码白边</param>
/// <returns>位图</returns>
public static Bitmap code(string msg, int version, int pixel, string icon_path, int icon_size, int icon_border, bool white_edge)
{
QRCodeGenerator code_generator = new QRCodeGenerator();
QRCodeData code_data = code_generator.CreateQrCode(msg, QRCodeGenerator.ECCLevel.L, true, true, QRCodeGenerator.EciMode.Utf8, version);
QRCode code = new QRCode(code_data);
//Bitmap icon = new Bitmap(icon_path);
Bitmap bmp = code.GetGraphic(pixel, Color.Black, Color.White, null, icon_size, icon_border, white_edge);
return bmp;
}
}
}
2、在控制器中创建方法进行调用,我们这里是在二维码中存储设备id,
//keyValue是设备的id,这里根据你们的需求来
private void CreateQrCode(int keyValue)
{
try
{
//检测文件夹是否存在【定义存放二维码的路径】
string strDirPath = System.AppDomain.CurrentDomain.BaseDirectory + "CheckDeviceQrCoderImg";
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
//物理路径【这里自定义图片的名称,可以用设备名称组成】
string QRCodePath = strDirPath + "\\图片名称.png";
if (!System.IO.File.Exists(QRCodePath))
{
//定义二维码内容,这里我是用小程序路径加设备id组成,用于小程序扫码跳转
string msg = $"/pages/cruise/runing?check_device_id={设备id}";
Bitmap qrCodeImage = QRCoderHelper.code(msg, 7, 5, null, 24, 1, true);
qrCodeImage.Save(QRCodePath);
//更新数据库设备地址
checkdeviceEntity.qrcode_path = string.Format("/CheckDeviceQrCoderImg/{0}.png", "图片名称");
//下面就是将图片地址更新及数据库,这里就不进行展示了
}
}
catch (System.Exception)
{
return "";
}
}
到此,c# 生成设备二维码的功能就已经完成了,但是生成的二维码的图片是这样的
并没有任何的文字说明,对于客户的使用是非常不方便的,所以这里我们准备将设别的名称及位置打印在图片的下方,
3、修改CreateQrCode方法
private void CreateQrCode(int keyValue)
{
try
{
//根据设备id查询设备信息,这里根据你们自己的代码来
var checkdeviceEntity = checkDeviceIBLL.GetEntity(keyValue);
//检测文件夹是否存在
string strDirPath = System.AppDomain.CurrentDomain.BaseDirectory + "CheckDeviceQrCoderImg";
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
//物理路径
string QRCodePath = strDirPath + "\\图片名称.png";
if (!System.IO.File.Exists(QRCodePath))
{
string msg = $"/pages/cruise/runing?check_device_id={checkdeviceEntity.设备id}";
Bitmap qrCodeImage = QRCoderHelper.code(msg, 7, 5, null, 28, 1, true);
//qrCodeImage.Save(QRCodePath);
//叠加图片
var pic = OverlayImage(qrCodeImage);
//叠加文本
var Picture = OverlayText(pic, checkdeviceEntity.设备名称, 245);
//var Picture1 = OverlayText(BitmapToImg(Picture), checkdeviceEntity.设备名称, 265);
var Picture1 = OverlayText(BitmapToImg(Picture), checkdeviceEntity.设备位置, 265);
//保存图片
Picture1.Save(QRCodePath);
//更新数据库设备地址
checkdeviceEntity.qrcode_path = string.Format("/CheckDeviceQrCoderImg/{0}.png", "图片名称");
//下面就是将图片地址更新及数据库,这里就不进行展示了
}
}
catch (System.Exception)
{
return "";
}
}
这里增加了几个方法,一个是图片叠加,另一个是图片上嵌入文字方法
/// <summary>
/// 图片叠加
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected Image OverlayImage(Bitmap lowerPic)
{
Bitmap upperPic = new Bitmap(lowerPic.Width, lowerPic.Height + 40);
var upperImg = BitmapToImg(upperPic);
var lowerImg = BitmapToImg(lowerPic);
using (Graphics g = Graphics.FromImage(upperImg))
{
g.DrawImage(lowerImg, new Rectangle(0,
0,
lowerImg.Width,
lowerImg.Height),
0, 0, lowerImg.Width, lowerImg.Height, GraphicsUnit.Pixel);
}
return upperImg;
}
/// 图片上嵌入文字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected Bitmap OverlayText(Image image, string name, int y)
{
using (Graphics g = Graphics.FromImage(image))
{
g.DrawImage(image, 265, 40, image.Width, image.Height);
using (Font f = new Font("宋体", 15))
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center; //居中
using (Brush b = new SolidBrush(Color.Black))
{
g.DrawString(name, f, b, 265 / 2, y, format);
}
}
}
return ImgToBitmap(image);
}
private Image BitmapToImg(Bitmap Bitmap)
{
try
{
Bitmap map = new Bitmap(Bitmap);
Image img = map;
return img;
}
catch (System.Exception)
{
throw;
}
}
private Bitmap ImgToBitmap(Image image)
{
try
{
Bitmap img = new Bitmap(image);
return img;
}
catch (Exception)
{
throw;
}
}
最终的效果是
到这里,图片追加文字的功能就已经完成啦。
4、下面给大家介绍微信小程序二维码的生成方式,这里先说下我的业务需求
客户想要一个停车优惠券的功能,需要用户微信扫描后,自动跳转到小程序中,首先明确一点,这个操作是需要调微信接口的,下面我们来实现下吧
//code为优惠券码,唯一值
public void CreateXcxQrCode(string code)
{
try
{
//首先建立文件夹
string strDirPath = System.AppDomain.CurrentDomain.BaseDirectory + "ParkingCouponQrCoderImg";
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
//这里需要使用小程序的appid及appsecret ,用户获取access_token
string URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + _appid + "&secret=" + appsecret + "";
string Date2 = HttpGet(URL);
Newtonsoft.Json.Linq.JObject _jObject = Newtonsoft.Json.Linq.JObject.Parse(Date2);
string access_token = _jObject["access_token"].ToString();
string page = "pages/car/carindex";//跳转的小程序路径
string width = "280";//二维码大小
string _url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token;
System.Net.HttpWebRequest request;
request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(_url);
request.Method = "POST";
request.ContentType = "application/json;charset=UTF-8";
//这里是参数
string scene = "index=0&code=" + code;
string options = "{\"scene\":\"" + scene + "\",\"page\":\"" + page + "\",\"width\":\"" + width + "\"}";
byte[] payload;
payload = System.Text.Encoding.UTF8.GetBytes(options);
request.ContentLength = payload.Length;
System.IO.Stream writer = request.GetRequestStream();
writer.Write(payload, 0, payload.Length);
writer.Close();
System.Net.HttpWebResponse response;
response = (System.Net.HttpWebResponse)request.GetResponse();
System.IO.Stream s;
s = response.GetResponseStream();
byte[] val = StreamToBytes(s);
string strdir_path= strDirPath +"\\"+code + ".png";
System.IO.File.WriteAllBytes(strdir_path, val);
s.Dispose();
writer.Dispose();
string path = string.Format("/ParkingCouponQrCoderImg/{0}.png", code);
//之后就是将path 更新进数据库了
}
catch (System.Exception ex)
{
throw;
}
} if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
public byte[] StreamToBytes(System.IO.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();
}
最后的效果为:
有兴趣的可以关注“墨水直达”,里面有许多免费的编程资料可以领取哦~