免费开源的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 条评论
登录 后参与评论

相关文章

来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

5228
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

5908
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

3005
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2997
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4395
来自专栏落花落雨不落叶

canvas画简单电路图

84611
来自专栏飞扬的花生

jsencrypt参数前端加密c#解密

      写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度...

4219
来自专栏魂祭心

原 canvas绘制clock

5094
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2936
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

7156

扫码关注云+社区