免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)

    在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码。无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码。二维码 (dimensional barcode) ,又称二维条码,是在一维条码的基础上扩展出的一种具有可读性的条码。设备扫描二维条码,通过识别条码的长度和宽度中所记载的二进制数据,可获取其中所包含的信息。相比一维条码,二维码记载更复杂的数据,比如图片、网络链接等。

    今天介绍一种免费开源的二维码操作组件,ThoughtWorks.QRCode组件可以高效而稳定的生成我们需要的二维码,接下来我们详细的了解一下这个组件。

一.ThoughtWorks.QRCode组件概述:

      QRCode库是一个.NET组件,可用于编码和解码QRCode。 QRCode是源自日本的二维条形码。 现在,它广泛应用于广泛的工业领域。 用于车辆部件跟踪和库存管理。QR代表“快速反应”。 它是日本公司Denso-Wave在1994年创建的,目的是高速解码内容。 如今,QR码被用于手机中以缓解数据输入。QRCode还可以打印在名片上或显示在任何显示器上,然后可以由移动电话捕获,只要移动电话具有读取QRCode的软件。QRCode库提供的功能包括:将内容编码为QR码图像,可以保存为JPEG,GIF,PNG或位图格式;解码QR码图像。

     该库可用于任何.NET 2.0 Windows应用程序,ASP.NET Web应用程序或Windows Mobile设备应用程序。以下是该组件的声明”本文以及任何相关的源代码和文件均已获得代码项目开放许可证(CPOL)许可“。

二.ThoughtWorks.QRCode相关核心对象和方法解析:

    有关ThoughtWorks.QRCode的主要类如下:

      以上是采用.NET Reflector对DLL文件进行反编译,以此查看源代码。由于我只是下载了DLL文件,没有下载源码,所以直接利用.NET Reflector查看源码,接下来具体介绍一下组件的一些类和方法:

   1.QRCodeEncoder:二维码编码类。

public enum ENCODE_MODE
{
    ALPHA_NUMERIC,
    NUMERIC,
    BYTE
}

public enum ERROR_CORRECTION
{
    L,
    M,
    Q,
    H
}

public virtual Bitmap Encode(string content, Encoding encoding)
{
    bool[][] flagArray = this.calQrcode(encoding.GetBytes(content));
    SolidBrush brush = new SolidBrush(this.qrCodeBackgroundColor);
    Bitmap image = new Bitmap((flagArray.Length * this.qrCodeScale) + 1, (flagArray.Length * this.qrCodeScale) + 1);
    Graphics graphics = Graphics.FromImage(image);
    graphics.FillRectangle(brush, new Rectangle(0, 0, image.Width, image.Height));
    brush.Color = this.qrCodeForegroundColor;
    for (int i = 0; i < flagArray.Length; i++)
    {
        for (int j = 0; j < flagArray.Length; j++)
        {
            if (flagArray[j][i])
            {
                graphics.FillRectangle(brush, j * this.qrCodeScale, i * this.qrCodeScale, this.qrCodeScale, this.qrCodeScale);
            }
        }
    }
    return image;
}

   2.QRCodeDecoder:二维码解码类。

public virtual string decode(QRCodeImage qrCodeImage, Encoding encoding)
{
    sbyte[] src = this.decodeBytes(qrCodeImage);
    byte[] dst = new byte[src.Length];
    Buffer.BlockCopy(src, 0, dst, 0, dst.Length);
    return encoding.GetString(dst);
}

 
public virtual sbyte[] decodeBytes(QRCodeImage qrCodeImage)
{
    DecodeResult result;
    Point[] adjustPoints = this.AdjustPoints;
    ArrayList list = ArrayList.Synchronized(new ArrayList(10));
    while (this.numTryDecode < adjustPoints.Length)
    {
        try
        {
            result = this.decode(qrCodeImage, adjustPoints[this.numTryDecode]);
            if (result.CorrectionSucceeded)
            {
                return result.DecodedBytes;
            }
            list.Add(result);
            canvas.println("Decoding succeeded but could not correct");
            canvas.println("all errors. Retrying..");
        }
        catch (DecodingFailedException exception)
        {
            if (exception.Message.IndexOf("Finder Pattern") >= 0)
            {
                throw exception;
            }
        }
        finally
        {
            this.numTryDecode++;
        }
    }
    if (list.Count == 0)
    {
        throw new DecodingFailedException("Give up decoding");
    }
    int num = -1;
    int numErrors = 0x7fffffff;
    for (int i = 0; i < list.Count; i++)
    {
        result = (DecodeResult) list[i];
        if (result.NumErrors < numErrors)
        {
            numErrors = result.NumErrors;
            num = i;
        }
    }
    canvas.println("All trials need for correct error");
    canvas.println("Reporting #" + num + " that,");
    canvas.println("corrected minimum errors (" + numErrors + ")");
    canvas.println("Decoding finished.");
    return ((DecodeResult) list[num]).DecodedBytes;
}

   3.QRCodeBitmapImage:位图图像。

public class QRCodeBitmapImage : QRCodeImage
{
    // Fields
    private Bitmap image;

    // Methods
    public QRCodeBitmapImage(Bitmap image);
    public virtual int getPixel(int x, int y);

    // Properties
    public virtual int Height { get; }
    public virtual int Width { get; }
}
public interface QRCodeImage
{
    // Methods
    int getPixel(int x, int y);

    // Properties
    int Height { get; }
    int Width { get; }
}

   以上是对ThoughtWorks.QRCode组件的一些方法的介绍,如果需要了解更多的方法,可以查看对应的源码。

三.ThoughtWorks.QRCode二维码操作实例:

    1.生成二维码(对二维码没有进行设置)。

        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="content">带生成二维码的字符串</param>
        /// <param name="path">路径</param>
        /// <returns></returns>
        public static string CreatehoughtWorksQrCode(string content, string path)
        {
            if (string.IsNullOrEmpty(content))
            {
                throw new ArgumentNullException(content);
            }
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(path);
            }
            var qrCodeEncoder = new QRCodeEncoder
            {
                QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE,
                QRCodeScale = 4,
                QRCodeVersion = 8,
                QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M
            };
            Image image = qrCodeEncoder.Encode(content);
            var filename = DateTime.Now.ToString("yyyymmddhhmmssfff") + ".jpg";
            var filepath = string.Format("{0}{1}", path, filename);
            FileStream fs = null;
            try
            {
                fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
                image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            catch (IOException ex)
            {
                throw new IOException(ex.Message);
            }
            finally
            {
                if (fs != null) fs.Close();
                image.Dispose();
            }
            return CodeDecoder(filepath);
        }

    2.选择生成二维码的相关类型。

        /// <summary>
        /// 选择生成二维码的相关类型
        /// <param name="strData">要生成的文字或者数字,支持中文。如: "4408810820 深圳-广州" 或者:4444444444</param>
        /// <param name="qrEncoding">三种尺寸:BYTE ,ALPHA_NUMERIC,NUMERIC</param>
        /// <param name="level">大小:L M Q H</param>
        /// <param name="version">版本:如 8</param>
        /// <param name="scale">比例:如 4</param>
        /// <returns></returns>
        /// </summary>
        public void CreateCode_Choose(string strData, string qrEncoding, string level, int version, int scale)
        {
            if (string.IsNullOrEmpty(strData))
            {
                throw new ArgumentNullException(strData);
            }
            if (string.IsNullOrEmpty(qrEncoding))
            {
                throw new ArgumentNullException(qrEncoding);
            }
            if (string.IsNullOrEmpty(level))
            {
                throw new ArgumentNullException(level);
            }
            var qrCodeEncoder = new QRCodeEncoder();
            var encoding = qrEncoding;
            switch (encoding)
            {
                case "Byte":
                    qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
                    break;
                case "AlphaNumeric":
                    qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.ALPHA_NUMERIC;
                    break;
                case "Numeric":
                    qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.NUMERIC;
                    break;
                default:
                    qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
                    break;
            }
            qrCodeEncoder.QRCodeScale = scale;
            qrCodeEncoder.QRCodeVersion = version;
            switch (level)
            {
                case "L":
                    qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L;
                    break;
                case "M":
                    qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
                    break;
                case "Q":
                    qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q;
                    break;
                default:
                    qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;
                    break;
            }
            Image image = null;
            FileStream fs = null;
            try
            {
                //文字生成图片
                image = qrCodeEncoder.Encode(strData);
                var filename = DateTime.Now.ToString("yyyymmddhhmmssfff") + ".jpg";
                var filepath = HttpContext.Current.Server.MapPath(@"~\Upload") + "\\" + filename;
                fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
                image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            catch (IOException ioex)
            {
                throw new IOException(ioex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (fs != null) fs.Close();
                if (image != null) image.Dispose();
            }
        }

   3.二维码解码。

        /// <summary>
        /// 二维码解码
        /// </summary>
        /// <param name="filePath">图片路径</param>
        /// <returns></returns>
        public static string CodeDecoder(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentNullException(filePath);
            }
            try
            {
                if (!File.Exists(filePath))
                    return null;
                var myBitmap = new Bitmap(Image.FromFile(filePath));
                var decoder = new QRCodeDecoder();
                var decodedString = decoder.decode(new QRCodeBitmapImage(myBitmap));
                return decodedString;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

四.总结:

    跟以前介绍组件一样,首先是组件的概述,组件的核心类,组件的使用方法,这些在这个组件时,找改组件的相关概述时,花了不少时间,也不知道为何,这个组件没有找到相关的资料,甚至连作者都是以某某某代替,最后还是在这里找到一些介绍:https://www.codeproject.com/articles/20574/open-source-qrcode-library。但是互联网就是如此,我们不需要知道是谁制造的,只要用起来方便就可以。在生成二维码的组件和js插件中,我个人还是喜欢这个组件的,感觉很不错,任何组件和方法都是有个人偏好和使用环境,读者可以自行根据情况选择。

    由于开发者提供了一个demo,可以直接进入上面的链接中查看下载,在这里就不做一个示例介绍。

.NET组件介绍系列:

    

  一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)

高效而稳定的企业级.NET Office 组件Spire(.NET组件介绍之二)

 最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)

免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)

免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)

免费高效实用的Excel操作组件NPOI(.NET组件介绍之六)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员八阿哥

年薪20万Python工程师进阶(7):Python资源大全,让你相见恨晚的Python库

用来访问第三方 API的库。 参见: List of Python API Wrappers and Libraries。

1562
来自专栏嵌入式程序猿

如何做好J1939应用层数据定义

SAE J1939 跟CANOpen,DeviceNet等一样都隶属于CAN的高层协议,J1939广泛应用于卡车,船舶,农林等设备,也正在拓展至其他的行业,因其...

773
来自专栏杨建荣的学习笔记

运维平台的建设思考-元数据管理(四)(r8笔记第16天)

对于服务器的一些信息,如果数据量大了之后总是感觉力不从心,需要了解,但是感觉得到的这些信息不够清晰明了。 比如我们得到一台服务器,需要知道最基本的硬件配置,内存...

36615
来自专栏个人分享

Linux知识体系之磁盘与档案系统管理

硬盘的物理组成:由许许多多的圆形硬盘盘所组成。宜居硬盘盘能够容纳的数据量,而有所谓的单碟或者多碟。

905
来自专栏吉浦迅科技

DAY73:阅读Programming Guidelines

我们正带领大家开始阅读英文的《CUDA C Programming Guide》,今天是第73天,我们正在讲解CUDA 动态并行,希望在接下来的27天里,您可以...

813
来自专栏草根专栏

使用angular4和asp.net core 2 web api做个练习项目(二), 这部分都是angular

完成client.service.ts: import { Injectable } from '@angular/core'; import { Http, ...

4725
来自专栏Spark生态圈

爬虫框架Scrapy(例子)前言安装实战

最近看到一篇非常不错的关于新词发现的论文--互联网时代的社会语言学:基于SNS的文本数据挖掘,迫不及待的想小试牛刀。得先有语料啊……

713
来自专栏java一日一条

如何分分钟成为Java嵌入式开发人员

在我10年的Java布道师生涯里,没有哪次Java新版本发布能让我如此兴奋。Java 8的发布不仅在语言本身加入了些不错的新特性,还在嵌入式开发上加入了很棒的功...

751
来自专栏知识分享

五,ESP8266 TCP服务器多连接(基于Lua脚本语言)

一些时间去准备朋友的元器件了... 接着写,,争取今天写完所有的文章,,因为答应了朋友下周5之前要做好朋友的东西 对于TCP大家在玩AT指令的时候有没有发现客户...

4857
来自专栏Hadoop实操

如何为服务器硬盘配置RAID或JBOD模式

在部署Hadoop平台的过程中,一般会要求数据盘配置RAID 0或者JBOD模式(直通模式),本文将详细讲解如何在HP dl380 Gen9服务器上配置RAID...

4072

扫码关注云+社区