• QRCode


    这个星期, 领导要我总结项目中用到的一些技术, 然后交付文档. 嘿嘿, 奉命整理. 

    二维码, 相信很多项目中都会要求生成这个, 然后由手机端去扫描, 或存储一些详情信息, 或存储一条链接, 可以快捷访问.

    一、示例

    public ActionResult QrCode()
    {
        var s = CreateQr("策士", "123456789", "", DateTime.Now.AddYears(-20), "15112341234");
    
        return File(s, "image/jpeg,image/png");
    }
    
    /// <summary>
    /// 生成二维码
    /// </summary>
    /// <returns>二维码相对路径</returns>
    public string CreateQr(string name, string code, string sex, DateTime birthday, string phone)
    {
        var codeParams = CodeDescriptor.Init(HttpContext.Request);
        var fileName = code + ".png";
        var path = Server.MapPath("~/QRCode/");
        var fullFileName = path + fileName;
    
        string content = string.Format("姓名:{0}
    编号:{1}
    性别:{2}
    年龄:{3}
    联系电话:{4}
    ",
                name,
                code,
                sex,
                (birthday.Year > 1000 ? (DateTime.Now.Year - birthday.Year).ToString() : ""),
                phone);
        codeParams.Content = content;
        // Encode the content
        codeParams.TryEncode();
        using (var ms = new MemoryStream())
        {
            codeParams.Render(ms);
    
            #region 保存图片
            var img = Image.FromStream(ms);
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            img.Save(fullFileName);
    
            #endregion
        }
        return fullFileName;
    }

    对这个二维码扫一扫, 就可以看到相关信息了.

    二、参数解析

    /// <summary>
    /// Parse QueryString that define the QR code properties
    /// </summary>
    /// <param name="request">HttpRequest containing HTTP GET data</param>
    /// <returns>A QR code descriptor object</returns>
    public static CodeDescriptor Init(HttpRequestBase request)
    {
        var cp = new CodeDescriptor();
    
        // Error correction level
        if (!Enum.TryParse(request.QueryString["e"], out cp.Ecl))
            cp.Ecl = ErrorCorrectionLevel.L;
    
        // Code content to encode
        cp.Content = request.QueryString["t"];
    
        // Size of the quiet zone
        if (!Enum.TryParse(request.QueryString["q"], out cp.QuietZones))
            cp.QuietZones = QuietZoneModules.Two;
    
        // Module size
        if (!int.TryParse(request.QueryString["s"], out cp.ModuleSize))
            cp.ModuleSize = 6;
    
        return cp;
    }

    1. 容错率

    二维码的容错率有四个级别, 不过我得先介绍一下什么叫二维码容错率.

    二维码容错率就是, 在二维码编码的时候, 进行冗余操作, 这种做法的目的, 就是希望二维码在有部分被遮挡的情况下, 还能扫描出正确结果. 就像abc编码成abcabc.

    public enum ErrorCorrectionLevel
    {
        L = 0,   //low 7%的字码可以被修正
        M = 1, //medium 15%
        Q = 2,  //quartile 25%
        H = 3,  //high  30%
    }

    测试方法, 其实就是拿着扫一扫, 对二维码扫描, 扫描的时候, 慢慢的将二维码放入扫描匡, 会发现, 其实并不需要完全放入扫描匡, 就已经能出结果了.

    容错率越高, 越容易快速扫描, 代价就是, 二维码编码的内容增多, 增加了二维码的复杂度.

    默认情况下, 会选择L.

    2. 空白

    public enum QuietZoneModules
    {
        Zero = 0,
        Two = 2,
        Four = 4,
    }

    这个属性, 表示二维码边上的空白区域的厚度, Zero表示没有空白边框, 最后的边框厚度, 是Two * 2 得到的. 

    3. 尺寸

    这里的 ModuleSize 就是二维码图片的尺寸, 尺寸越大, 能容纳信息越多.

    4. 内容编码

     二维码内容默认编码为utf-8, 

    这里还有一些别的属性, 比如背景颜色, 绘制颜色之类的, 就不一一细说了

    二维码的内容长度限制, 在文档中, 并没有找到, Api文档中说,  少到1个字符, 多到900个字符, 二维码都是能正常显示的. 当然, 二维码存储信息不易过多. The shorter the better.

    如果内容过多, 可以通过二维码提供链接的方式, 让用户去请求接口, 而不是通过扫描二维码直接得到内容.

    具体方法, 就是

     codeParams.Content = "http://www.baidu.com";

    这里的http://是必须要的, 否则会将内容当做普通字符去解析

    最后, 贴上完整的封装:

    /// <summary>
    /// Class containing the description of the QR code and wrapping encoding and rendering.
    /// </summary>
    public class CodeDescriptor
    {
        public ErrorCorrectionLevel Ecl;
        public string Content;
        public QuietZoneModules QuietZones;
        public int ModuleSize;
        public BitMatrix Matrix;
        public string ContentType;
    
        /// <summary>
        /// Parse QueryString that define the QR code properties
        /// </summary>
        /// <param name="request">HttpRequest containing HTTP GET data</param>
        /// <returns>A QR code descriptor object</returns>
        public static CodeDescriptor Init(HttpRequestBase request)
        {
            var cp = new CodeDescriptor();
    
            // Error correction level
            if (!Enum.TryParse(request.QueryString["e"], out cp.Ecl))
                cp.Ecl = ErrorCorrectionLevel.L;
    
            // Code content to encode
            cp.Content = request.QueryString["t"];
    
            // Size of the quiet zone
            if (!Enum.TryParse(request.QueryString["q"], out cp.QuietZones))
                cp.QuietZones = QuietZoneModules.Two;
    
            // Module size
            if (!int.TryParse(request.QueryString["s"], out cp.ModuleSize))
                cp.ModuleSize = 6;
    
            return cp;
        }
    
        /// <summary>
        /// Parse QueryString that define the QR code properties
        /// </summary>
        /// <param name="request">HttpRequest containing HTTP GET data</param>
        /// <returns>A QR code descriptor object</returns>
        public static CodeDescriptor Init(HttpRequest request)
        {
            var cp = new CodeDescriptor();
    
            // Error correction level
            if (!Enum.TryParse(request.QueryString["e"], out cp.Ecl))
                cp.Ecl = ErrorCorrectionLevel.L;
    
            // Code content to encode
            cp.Content = request.QueryString["t"];
    
            // Size of the quiet zone
            if (!Enum.TryParse(request.QueryString["q"], out cp.QuietZones))
                cp.QuietZones = QuietZoneModules.Two;
    
            // Module size
            if (!int.TryParse(request.QueryString["s"], out cp.ModuleSize))
                cp.ModuleSize = 6;
    
            return cp;
        }
    
        /// <summary>
        /// Encode the content with desired parameters and save the generated Matrix
        /// </summary>
        /// <returns>True if the encoding succeeded, false if the content is empty or too large to fit in a QR code</returns>
        public bool TryEncode()
        {
            var encoder = new QrEncoder(Ecl);
            QrCode qr;
            if (!encoder.TryEncode(Content, out qr))
                return false;
    
            Matrix = qr.Matrix;
            return true;
        }
    
        /// <summary>
        /// Render the Matrix as a PNG image
        /// </summary>
        /// <param name="ms">MemoryStream to store the image bytes into</param>
        public void Render(MemoryStream ms)
        {
            var render = new GraphicsRenderer(new FixedModuleSize(ModuleSize, QuietZones));
            render.WriteToStream(Matrix, ImageFormat.Png, ms);
            ContentType = "image/png";
        }
    }
    二维码

    参考:

    二维码详解

    qrcodenet代码中一些基础的认识 帮助

    api

  • 相关阅读:
    分布式系统中的Session问题
    HotSpot VM运行时---命令行选项解析
    K大数查询
    [DarkBZOJ3636] 教义问答手册
    小朋友和二叉树
    [COCI2018-2019#2] Sunčanje
    小SY的梦
    [HDU6722 & 2019百度之星初赛四 T4] 唯一指定树
    [HDU6800] Play osu! on Your Tablet
    [NOI2007] 货币兑换
  • 原文地址:https://www.cnblogs.com/elvinle/p/6197351.html
Copyright © 2020-2023  润新知