详解二维码生成工厂
作者:神牛步行3 发布时间:2022-09-26 11:26:13
本次主要分享的是3个免费的二维码接口的对接代码和测试得出的注意点及区别,有更好处理方式多多交流,相互促进进步;最近在学习JavsScript的扩展TypeScript,感觉语法糖很甜,大部分与C#更为类似,可能都是微软项目的原因吧,有兴趣的朋友可以多多相互交流下;
以上是个人的看法,下面来正式分享今天的文章吧:
Google的Api二维码生成接口
2d-code的Api二维码生成接口
topscan的Api二维码生成接口
使用面向对象+加载程序集创建对象合并以上接口封装成二维码生成工厂
下面一步一个脚印的来分享:
Google的Api二维码生成接口
首先,这里给出Google接口文档的链接qr_codes文档,热情的朋友马上就会打开此链接吧,详细看下里面的参数这就不做截图了,大致通常用到的参数是:api地址,内容参数,生成图片的高宽这3个参数,其他的几个参数都采用默认的吧,不同需要大家可以更详细的看下;其实第一次看到文档里面的参数,感觉少了一些东西,比如怎么不能传递二维码中间那个图标的图片地址和扫描二维码过后怎么跳转到我想重定向的url链接呢,带着这个疑问我进行了多次的尝试;下面给出自己尝试的结果说明:
接口关键参数是:cht(固定值qr),chl(内容参数),chs(生成出来二维码图片尺寸,格式如:200x200,这里是xyz的x不是*)
api接口只会生成一个二维码的图片流,如果需要把图片保存到本地需要通过浏览器直接get访问接口或者通过程序下载这个二维码
内容参数如果传递文本信息,在生成出来的二维码图片中间不会显示文本内容,只有用手机扫描二维码才能在手机上显示传递的文本信息
内容参数如果传递单纯的http://格式的链接地址,那么手机扫描后会自动重定向到改http://链接地址上(这个扫描重定向可以用来做一些商品或者文章的查看)
google接口暂未研究出此Logo图标地址参数(希望有朋友研究出来后与我分享,谢谢)
由于api地址是国外的,调用接口响应不是那么快速
其次,上面是个人的一些总结,下面我们来看下封装的请求接口方法和下载二维码图片方法:
#region 生成二维码
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="content">展示内容(文本内容 或者 扫描后的跳转http://格式的地址)</param>
/// <param name="savePath">保存二维码的磁盘路径(默认程序跟目录+QRCode)</param>
/// <param name="logoUrl"> Logo图标地址(格式:http://),(注:google接口暂未研究出此参数)</param>
/// <param name="apiUrl">接口地址(内置默认api地址)</param>
/// <param name="wAndh">宽度和高度(二维码正方形的,高宽一至,默认200)</param>
/// <returns></returns>
public virtual string CreateQRCode(string content = null, string savePath = null, string logoUrl = null, string apiUrl = null, int? wAndh = null)
{
var qrName = string.Empty;
#region 参数初始化
ApiUrl = apiUrl ?? ApiUrl;
Content = content ?? Content;
SaveQRPath = savePath ?? SaveQRPath;
LogoUrl = logoUrl ?? LogoUrl;
WAndH = wAndh ?? WAndH;
#endregion
if (string.IsNullOrEmpty(ApiUrl)) { return qrName; }
ApiUrl = string.Format("{0}?cht=qr&chl={1}&chs={2}x{2}",
ApiUrl,
HttpUtility.UrlEncode(Content),
WAndH);
qrName = DownImg(ApiUrl, SaveQRPath, ImageFormat.Jpeg);
return qrName;
}
#endregion
下载二维码图片保存到程序根目录:
#region 下载图片
/// <summary>
/// 下载图片
/// </summary>
/// <param name="url">图片下载地址</param>
/// <param name="savePath">保存路径默认:Img文件夹</param>
/// <param name="format">默认:Jpeg</param>
/// <returns>新图片名称</returns>
public virtual string DownImg(string url, string savePath = "QRCode", ImageFormat format = null)
{
var qrName = string.Empty;
try
{
format = format ?? ImageFormat.Jpeg;
HttpClient http = new HttpClient();
http.Timeout = new TimeSpan(0, 1, 0);
using (var stream = http.GetStreamAsync(url).Result)
{
if (!Directory.Exists(SaveQRPath)) { Directory.CreateDirectory(SaveQRPath); }
qrName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "." + format;
var path = Path.Combine(savePath, qrName);
using (Image img = Image.FromStream(stream))
{
img.Save(path, format);
}
}
}
catch (Exception ex)
{
qrName = string.Empty;
}
return qrName;
}
#endregion
上面两个方法使用的是虚方法,因为我这里是吧google接口当做默认的二维码生成器来使用,后面要讲的另外两个接口都是重写与此;下载图片的方法都是公用的,暂不需要重写;这里需要提到的是调用api接口时有一个固定的参数cht=qr,这个参数表示采用QR方法生成二维码,因为这个api接口还有生成图标的功能,所以只想要生成二维码这里就固定,更多的生成图标功能不在本章分享中,谢谢。
2d-code的Api二维码生成接口
首先,该接口需要通过他们官网注册一个key,然后从后台获取到这个key后才能调用接口地址,当然注册后有个功能是,凡是您通过api接口生成的二维码,除了自己通过流下载,还能通过他们后台一起下载所有生成的图片,本人暂时没有去关注是否生成量大了会收费哈哈,下面列举下接口参数说明和测试得出的注意点:
接口关键参数是:key(注册获取),text(文本参数),url(扫描后重定向地址),logo(Logo图标地址),size(二维码正方形,高宽)
接口的文本参数只能传递文本,不能当做扫描后重定向的地址参数使用和Google等接口有点不一样
扫描后重定向地址和Logo图标地址都是可访问的http://格式的地址链接
Logo图标地址,官方说不建议使用png格式,测试只有jpg成功(可能是测试不够多这里只单纯介绍我的结果)
生成速度比较快,而且还有一个艺术字的生成接口,挺不错
api接口只会生成一个二维码的图片流,如果需要把图片保存到本地需要通过浏览器直接get访问接口或者通过程序下载这个二维码
其次,下面给出封装的代码,由于下载和上面介绍的代码一样是公用的这里就不做陈述:
public QR_2dCode()
{
ApiUrl = "http://www.2d-code.cn/2dcode/api.php";
}
#region 生成二维码
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="content">展示内容(文本内容 或者 扫描后的跳转http://格式的地址)</param>
/// <param name="savePath">保存二维码的磁盘路径(默认程序跟目录+QRCode)</param>
/// <param name="logoUrl"> Logo图标地址(格式:http://),官方不建议使用png格式,测试只有jpg成功</param>
/// <param name="directUrl">扫描后重定向地址(http://)</param>
/// <param name="apiUrl">接口地址(内置默认api地址)</param>
/// <param name="wAndh">宽度和高度(二维码正方形的,高宽一至,默认200)</param>
/// <returns></returns>
public override string CreateQRCode(string content = null, string savePath = null, string logoUrl = null, string apiUrl = null, int? wAndh = null)
{
var qrName = string.Empty;
#region 参数初始化
ApiUrl = apiUrl ?? ApiUrl;
Content = content ?? Content;
SaveQRPath = savePath ?? SaveQRPath;
LogoUrl = logoUrl ?? LogoUrl;
WAndH = wAndh ?? WAndH;
#endregion
if (string.IsNullOrEmpty(ApiUrl)) { return qrName; }
ApiUrl = string.Format("{0}?key=c_d800OBbu6hDzJtXPE2Yd02IMtmpuK9VdCqHe6vrtar4&text={1}&url={2}&logo={3}&size={4}",
ApiUrl,
HttpUtility.UrlEncode(Content.Contains("http") ? "" : Content),
HttpUtility.UrlEncode(Content),
HttpUtility.UrlEncode(LogoUrl),
WAndH);
qrName = DownImg(ApiUrl, SaveQRPath);
return qrName;
}
#endregion
topscan的Api二维码生成接口
首先,该接口肯定是免费的,参数描述和google的差不多,不同处在于可以传递Logo图标地址(当然可能我还没发现google的可以传递logo的参数,故此朋友们可以忽略);下面列举下接口参数说明和测试得出的注意点:
接口关键参数是:text(内容参数),logo(Logo图标地址),w(生成出来二维码图片尺寸,格式如:200x200,这里是xyz的x不是*)
api接口只会生成一个二维码的图片流,如果需要把图片保存到本地需要通过浏览器直接get访问接口或者通过程序下载这个二维码
内容参数如果传递文本信息,在生成出来的二维码图片中间不会显示文本内容,只有用手机扫描二维码才能在手机上显示传递的文本信息
内容参数如果传递单纯的http://格式的链接地址,那么手机扫描后会自动重定向到改http://链接地址上(这个扫描重定向可以用来做一些商品或者文章的查看)
Logo图标地址(格式:http://),jpg,png测试通过
测试得出有时候请求生成二维码不返回数据,有可能是我网路问题吧,正常生成二维码的速度还是挺快
其次,下面给出封装的代码,由于下载和上面介绍的代码一样是公用的这里就不做陈述:
public QR_TopScan()
{
ApiUrl = "http://qr.topscan.com/api.php";
}
#region 生成二维码
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="content">展示内容(文本内容 或者 扫描后的跳转http://格式的地址)</param>
/// <param name="savePath">保存二维码的磁盘路径(默认程序跟目录+QRCode)</param>
/// <param name="logoUrl"> Logo图标地址(格式:http://),jpg,png测试通过,测试得出有不能成功的,原因不知是否和地址有关</param>
/// <param name="apiUrl">接口地址(内置默认api地址)</param>
/// <param name="wAndh">宽度和高度(二维码正方形的,高宽一至,默认200)</param>
/// <returns></returns>
public override string CreateQRCode(string content = null, string savePath = null, string logoUrl = null, string apiUrl = null, int? wAndh = null)
{
var qrName = string.Empty;
#region 参数初始化
ApiUrl = apiUrl ?? ApiUrl;
Content = content ?? Content;
SaveQRPath = savePath ?? SaveQRPath;
LogoUrl = logoUrl ?? LogoUrl;
WAndH = wAndh ?? WAndH;
#endregion
if (string.IsNullOrEmpty(ApiUrl)) { return qrName; }
ApiUrl = string.Format("{0}?text={1}&logo={2}&w={3}",
ApiUrl,
HttpUtility.UrlEncode(Content),
HttpUtility.UrlEncode(LogoUrl),
WAndH);
qrName = DownImg(ApiUrl, SaveQRPath);
return qrName;
}
#endregion
使用面向对象+加载程序集创建对象合并以上接口封装成二维码生成工厂
首先,分析上面3个接口的参数可以看出,都需要固定的参数:接口api,内容(文本或跳转http地址),Logo图片地址(google暂时除外),宽度和高度等这几个参数,这样一来咋们可以定义个统一参数类,来传递该参数信息,这里还要提下由于这几个接口都是从别人接口获取图片流,如果想要吧图片在执行程序时候直接保存在我们的程序本地,都需要下载,所以又多一个参数: 保存二维码的磁盘路径,所以才有了一下公共的属性:
#region 基础配置信息
/// <summary>
/// 接口地址(必填)
/// </summary>
protected string ApiUrl = "https://chart.googleapis.com/chart";
/// <summary>
/// 展示内容(文本内容),google文本参数直接传递http地址直接重定向
/// </summary>
protected string Content = "http://www.cnblogs.com/wangrudong003/";
/// <summary>
/// 保存二维码的磁盘路径(默认程序跟目录+QRCode)
/// </summary>
protected string SaveQRPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "QRCode");
/// <summary>
/// Logo图片地址(http://)
/// </summary>
protected string LogoUrl = "http://a.hiphotos.baidu.com/baike/w%3D268%3Bg%3D0/sign=9a34e44d8bd4b31cf03c93bdbfed4042/2cf5e0fe9925bc318cb9fe965edf8db1ca1370dc.jpg";
/// <summary>
/// 宽度和高度(二维码正方形的,高宽一至,默认200)
/// </summary>
protected int WAndH = 200;
#endregion
然后,这里我不想每个接口都手动new一次来创建对象,所以用了加载程序集的模块的方式来创建所需要的对象,因此有了工厂类的入口:
/// <summary>
/// 二维码生成工厂
/// </summary>
public class QRCodeReposity
{
public static BaseQRCode Current(QREmType qrEmType = QREmType.BaseQRCode)
{
var nspace = typeof(BaseQRCode);
var fullName = nspace.FullName;
var nowspace = fullName.Substring(0, fullName.LastIndexOf('.') + 1);
return Assembly.GetExecutingAssembly().CreateInstance(nowspace + qrEmType.ToString(), true) as BaseQRCode;
}
}
这里和之前的缓存工厂文章设计差不多,可以查阅下之前的分享篇,也多多点赞,谢谢;下面在给出说有的代码如下:
/// <summary>
/// 工厂模块定义
/// </summary>
public enum QREmType
{
/// <summary>
/// google接口
/// </summary>
BaseQRCode,
/// <summary>
/// 2d-code接口
/// </summary>
QR_2dCode,
/// <summary>
/// topscan接口
/// </summary>
QR_TopScan
}
/// <summary>
/// 二维码生成工厂
/// </summary>
public class QRCodeReposity
{
public static BaseQRCode Current(QREmType qrEmType = QREmType.BaseQRCode)
{
var nspace = typeof(BaseQRCode);
var fullName = nspace.FullName;
var nowspace = fullName.Substring(0, fullName.LastIndexOf('.') + 1);
return Assembly.GetExecutingAssembly().CreateInstance(nowspace + qrEmType.ToString(), true) as BaseQRCode;
}
}
/// <summary>
/// 基类使用Google提供Api:https://developers.google.com/chart/infographics/docs/qr_codes ,由于是国外地址,相对来说有点慢
/// </summary>
public class BaseQRCode
{
#region 基础配置信息
/// <summary>
/// 接口地址(必填)
/// </summary>
protected string ApiUrl = "https://chart.googleapis.com/chart";
/// <summary>
/// 展示内容(文本内容),google文本参数直接传递http地址直接重定向
/// </summary>
protected string Content = "http://www.cnblogs.com/wangrudong003/";
/// <summary>
/// 保存二维码的磁盘路径(默认程序跟目录+QRCode)
/// </summary>
protected string SaveQRPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "QRCode");
/// <summary>
/// Logo图片地址(http://)
/// </summary>
protected string LogoUrl = "http://a.hiphotos.baidu.com/baike/w%3D268%3Bg%3D0/sign=9a34e44d8bd4b31cf03c93bdbfed4042/2cf5e0fe9925bc318cb9fe965edf8db1ca1370dc.jpg";
/// <summary>
/// 宽度和高度(二维码正方形的,高宽一至,默认200)
/// </summary>
protected int WAndH = 200;
#endregion
#region 方法
#region 生成二维码
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="content">展示内容(文本内容 或者 扫描后的跳转http://格式的地址)</param>
/// <param name="savePath">保存二维码的磁盘路径(默认程序跟目录+QRCode)</param>
/// <param name="logoUrl"> Logo图标地址(格式:http://),(注:google接口暂未研究出此参数)</param>
/// <param name="apiUrl">接口地址(内置默认api地址)</param>
/// <param name="wAndh">宽度和高度(二维码正方形的,高宽一至,默认200)</param>
/// <returns></returns>
public virtual string CreateQRCode(string content = null, string savePath = null, string logoUrl = null, string apiUrl = null, int? wAndh = null)
{
var qrName = string.Empty;
#region 参数初始化
ApiUrl = apiUrl ?? ApiUrl;
Content = content ?? Content;
SaveQRPath = savePath ?? SaveQRPath;
LogoUrl = logoUrl ?? LogoUrl;
WAndH = wAndh ?? WAndH;
#endregion
if (string.IsNullOrEmpty(ApiUrl)) { return qrName; }
ApiUrl = string.Format("{0}?cht=qr&chl={1}&chs={2}x{2}",
ApiUrl,
HttpUtility.UrlEncode(Content),
WAndH);
qrName = DownImg(ApiUrl, SaveQRPath, ImageFormat.Jpeg);
return qrName;
}
#endregion
#region 下载图片
/// <summary>
/// 下载图片
/// </summary>
/// <param name="url">图片下载地址</param>
/// <param name="savePath">保存路径默认:Img文件夹</param>
/// <param name="format">默认:Jpeg</param>
/// <returns>新图片名称</returns>
public virtual string DownImg(string url, string savePath = "QRCode", ImageFormat format = null)
{
var qrName = string.Empty;
try
{
format = format ?? ImageFormat.Jpeg;
HttpClient http = new HttpClient();
http.Timeout = new TimeSpan(0, 1, 0);
using (var stream = http.GetStreamAsync(url).Result)
{
if (!Directory.Exists(SaveQRPath)) { Directory.CreateDirectory(SaveQRPath); }
qrName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "." + format;
var path = Path.Combine(savePath, qrName);
using (Image img = Image.FromStream(stream))
{
img.Save(path, format);
}
}
}
catch (Exception ex)
{
qrName = string.Empty;
}
return qrName;
}
#endregion
#endregion
}
/// <summary>
/// 使用2d-code提供Api,需要去官网注册获取Key
/// </summary>
public class QR_2dCode : BaseQRCode
{
public QR_2dCode()
{
ApiUrl = "http://www.2d-code.cn/2dcode/api.php";
}
#region 生成二维码
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="content">展示内容(文本内容 或者 扫描后的跳转http://格式的地址)</param>
/// <param name="savePath">保存二维码的磁盘路径(默认程序跟目录+QRCode)</param>
/// <param name="logoUrl"> Logo图标地址(格式:http://),官方不建议使用png格式,测试只有jpg成功</param>
/// <param name="directUrl">扫描后重定向地址(http://)</param>
/// <param name="apiUrl">接口地址(内置默认api地址)</param>
/// <param name="wAndh">宽度和高度(二维码正方形的,高宽一至,默认200)</param>
/// <returns></returns>
public override string CreateQRCode(string content = null, string savePath = null, string logoUrl = null, string apiUrl = null, int? wAndh = null)
{
var qrName = string.Empty;
#region 参数初始化
ApiUrl = apiUrl ?? ApiUrl;
Content = content ?? Content;
SaveQRPath = savePath ?? SaveQRPath;
LogoUrl = logoUrl ?? LogoUrl;
WAndH = wAndh ?? WAndH;
#endregion
if (string.IsNullOrEmpty(ApiUrl)) { return qrName; }
ApiUrl = string.Format("{0}?key=c_d800OBbu6hDzJtXPE2Yd02IMtmpuK9VdCqHe6vrtar4&text={1}&url={2}&logo={3}&size={4}",
ApiUrl,
HttpUtility.UrlEncode(Content.Contains("http") ? "" : Content),
HttpUtility.UrlEncode(Content),
HttpUtility.UrlEncode(LogoUrl),
WAndH);
qrName = DownImg(ApiUrl, SaveQRPath);
return qrName;
}
#endregion
}
/// <summary>
/// 使用topscan提供Api
/// </summary>
public class QR_TopScan : BaseQRCode
{
public QR_TopScan()
{
ApiUrl = "http://qr.topscan.com/api.php";
}
#region 生成二维码
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="content">展示内容(文本内容 或者 扫描后的跳转http://格式的地址)</param>
/// <param name="savePath">保存二维码的磁盘路径(默认程序跟目录+QRCode)</param>
/// <param name="logoUrl"> Logo图标地址(格式:http://),jpg,png测试通过,测试得出有不能成功的,原因不知是否和地址有关</param>
/// <param name="apiUrl">接口地址(内置默认api地址)</param>
/// <param name="wAndh">宽度和高度(二维码正方形的,高宽一至,默认200)</param>
/// <returns></returns>
public override string CreateQRCode(string content = null, string savePath = null, string logoUrl = null, string apiUrl = null, int? wAndh = null)
{
var qrName = string.Empty;
#region 参数初始化
ApiUrl = apiUrl ?? ApiUrl;
Content = content ?? Content;
SaveQRPath = savePath ?? SaveQRPath;
LogoUrl = logoUrl ?? LogoUrl;
WAndH = wAndh ?? WAndH;
#endregion
if (string.IsNullOrEmpty(ApiUrl)) { return qrName; }
ApiUrl = string.Format("{0}?text={1}&logo={2}&w={3}",
ApiUrl,
HttpUtility.UrlEncode(Content),
HttpUtility.UrlEncode(LogoUrl),
WAndH);
qrName = DownImg(ApiUrl, SaveQRPath);
return qrName;
}
#endregion
}
本篇的分享内容在程序设计方面没有太多,重点是分装下这几个接口和分享下接口的差异,方面朋友们可以拿来主义和正在对接二维码生成的朋友做下交流,仅此而已;关键代码的备注都在分享代码里,有更好或者不清楚的地方欢迎留言,谢谢。
来源:http://www.cnblogs.com/wangrudong003/p/5854094.html


猜你喜欢
- 用户退出应用前给出一个提示是很有必要的,因为可能是用户并不真的想退出,而只是一不小心按下了返回键,大部分应用的做法是在应用退出去前给出一个D
- 1.点击上传按钮进行如下操作,通过表单名称以及input名称获取相应的值,对于上传的文件,使用.files来获取,因为包含文件的上传,所以采
- 目录Demo展示介绍计时器功能Unity计时器Demo展示介绍游戏中有非常多的计时功能,比如:各种cd,以及需要延时调用的方法;一般实现有一
- C# 泛型(Generic)定义:泛型允许我们延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。也就是说,泛型是可
- 1.什么是并行计算传统并行计算:共享同一个数据,通过锁来控制数据的读写,难度大,容易导致死锁,拓展性差。但是是实时的,细颗粒度计算,计算密集
- java 基础之final、finally和finalize的区别1.final可以修饰类,不能被继承;可以修饰方法,不能被重写;可以修饰变
- 1.定义字符串字符串常见的构造方式如下:String s1 = "with";String s2 = new Strin
- JAVA操作XML文档主要有四种方式,分别是DOM、SAX、JDOM和DOM4J,DOM和SAX是官方提供的,而JDOM和DOM4J则是引用
- 一、项目简述功能: 前后用户的登录注册,婚纱照片分类,查看,摄影师预 订,后台订单管理,图片管理等等。二、项目运行环境配置: Jdk1.8
- 概述从今天开始, 小白我将带大家开启 Jave 数据结构 & 算法的新篇章.循环队列循环队列 (Circular Queue) 是一
- 一、deleteById 和 delete为什么要把这两个方法放在一起呢?我们先看源码再说deleteById(Id id)(通过id进行删
- C#是一门强类型语言,一般情况下最好避免将一个类型转换成另一个类型,但是有些时候又不得不进行类型转换,那么就出现几种强转方式。1. 括号强转
- 最近都在忙着写一个网站项目,今天做一个分页功能的时候,遇到了分页效果实现不了的问题,查了好久的资料,后来终于是成功解决啦,记录一下1.在po
- 前言本文主要学习函数的相关内容。1、函数是什么? * 中对函数的定义:子程序在计算机科学中,子程序(英语:Subroutine, proc
- 本文实例讲述了WinForm实现最小化到系统托盘方法。分享给大家供大家参考。具体分析如下:有个叫NotifyIcon的控件1、建个WinFo
- 这个导出网站功能指通过前台javascript触发进入ashx函数中,实现将服务器中某个文件夹(包含其子文件夹和文件)通通复制到服务器中另一
- 1. SpEL 回顾经过上篇文章的学习,小伙伴们已经知道了,在 Spring Security 中,@PreAuthorize、@PostA
- 前言Feign是Netflix开源的声明式HTTP客户端,致力于让编写http client更加简单,Feign可以通过声明接口自动构造请求
- 一、this关键字this是一个引用,它指向自身的这个对象。看内存分析图:假设我们在堆内存new了一个对象,在这个对象里面你想象着他有一个引
- 本文实例为大家分享了WheelPicker自定义时间选择器控件的具体代码,供大家参考,具体内容如下先上图:使用android自带的DateP