C#WinForm二维码编码解码器

使用ThoughtWorks.QRCode组件,该组件是一个免费开源的二维码操作动态链接库,在进行程序编写实现该系统的过程中,应先将ThoughtWorks.QRCode.dll文件通过“添加引用”进行添加,在程序中添加指令集:

using ThoughtWorks.QRCode.Codec;
using ThoughtWorks.QRCode.Codec.Data;
using ThoughtWorks.QRCode.Codec.Util;

通过引用该组件中封装的相应的类来实现二维码的生成和解码。其中封装的QRCodeEncoder为二维码编码类,QRCodeDecoder为二维码解码类,QRCodeBitmapImage为位图图像生成类,该类库具体的源码:

1.ORCodeEncoder:二维码编码类

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; }
}

采用C#WinForm进行二维码编码和解码系统的实现,详细代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using ThoughtWorks.QRCode.Codec;
using ThoughtWorks.QRCode.Codec.Data;
using ThoughtWorks.QRCode.Codec.Util;
using System.IO;

using ControlExs;


namespace WindowsQRCode11_22
{
    public partial class Form1 : Form
    {
        private const long WM_GETMINMAXINFO = 0x24;

        public struct POINTAPI
        {
            public int x;
            public int y;
        }

        public struct MINMAXINFO
        {
            public POINTAPI ptReserved;
            public POINTAPI ptMaxSize;
            public POINTAPI ptMaxPosition;
            public POINTAPI ptMinTrackSize;
            public POINTAPI ptMaxTrackSize;
        }

        public Form1()
        {
            InitializeComponent();
            this.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height);
            cbVersion.Text = "7";
            cbEncoding.Text = "Byte";
            cbCorrectionLevel.Text = "M";
            txtData.Text = "请输入数据内容...";  
            cbScale.Text = "5";
            btnQRCodeForegroundColor.BackColor = System.Drawing.Color.Black;
            btnQRCodeBackgroundColor.BackColor = System.Drawing.Color.White;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;    //最大化窗体
        }
        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == WM_GETMINMAXINFO)
            {
                MINMAXINFO mmi = (MINMAXINFO)m.GetLParam(typeof(MINMAXINFO));
                mmi.ptMinTrackSize.x = this.MinimumSize.Width;
                mmi.ptMinTrackSize.y = this.MinimumSize.Height;
                if (this.MaximumSize.Width != 0 || this.MaximumSize.Height != 0)
                {
                    mmi.ptMaxTrackSize.x = this.MaximumSize.Width;
                    mmi.ptMaxTrackSize.y = this.MaximumSize.Height;
                }
                mmi.ptMaxPosition.x = 1;
                mmi.ptMaxPosition.y = 1;

                System.Runtime.InteropServices.Marshal.StructureToPtr(mmi, m.LParam, true);
            }
        }


        //解决窗体闪烁
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                if (!DesignMode)
                {
                    cp.ExStyle |= (int)WindowStyle.WS_CLIPCHILDREN;
                }
                return cp;

            }
        }


        //生成二维码
        private void button1_Click(object sender, EventArgs e)
        {
            button8.Visible = true;
            string encoding = cbEncoding.Text;
            string correctionLever = cbCorrectionLevel.Text;
            int version = Convert.ToInt32(cbVersion.Text);
            int scale = Convert.ToInt32(cbScale.Text);
            string data = txtData.Text.Trim();
            if (data == string.Empty)
            {
                MessageBox.Show("请输入数据!","警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (data == "请输入数据内容...")
            {
                DialogResult dr = MessageBox.Show("您确定输入的数据内容为:“请输入数据内容...”吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                if (dr == DialogResult.Cancel)
                {
                    txtData.Text = "";
                    return;
                }
                else
                {
                    txtData.Text = "请输入数据内容...";
                }
            }

            QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();//创建一个对象


            //设置编码模式 
            //当设定目标图片尺寸小于生成的尺寸时,逐步减小方格尺寸
            //二维码编码(Byte、AlphaNumeric、Numeric)
            /*byte模式,可以支持汉字、英文字母、数字、特殊符号等
            Alphanumeric为混合模式,支持的二维码内容:英文大写字母、数字、9个特殊符号,英文小写字母识别为0
            Numeric:二维码内容为纯数字
            1) numeric data (digits 0 - 9);
            2) alphanumeric data (digits 0 - 9; upper case letters A -Z; nine other characters: space, $ % * + - . / : );*/
            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;
            }


            #region//设置编码测量度:值越大生成的二维码图片像素越高
            //二维码尺寸(Version为0时,1:26x26,每加1宽和高各加25
            #endregion
            qrCodeEncoder.QRCodeScale = scale;
            #region//设置编码版本 
            //二维码密集度0 - 40
            /*二维码一共有40个尺寸。官方叫版本Version。
            Version 1是21 x 21的矩阵
            Version 2是 25 x 25的矩阵
            Version 3是29的尺寸
            每增加一个version,就会增加4的尺寸
            (V-1)*4 + 21(V是版本号) 
            最高Version 40,(40-1)*4+21 = 177,所以最高是177 x 177 的正方形
            There are forty sizes of QR Code symbol referred to as Version 1, Version 2 ... Version 40. Version 1 measures 21
            modules  21 modules, Version 2 measures 25 modules  25 modules and so on increasing in steps of 4 modules
            per side up to Version 40 which measures 177 modules  177 modules. Figures 3 to 8 illustrate the structure of
            Versions 1, 2, 6, 7, 14, 21 and 40.*/
            #endregion

            qrCodeEncoder.QRCodeVersion = version;


            #region//设置编码错误纠正
            //二维码纠错能力(L:7% M:15% Q:25% H:30%)
            //L->H:修正的错误增加,对应二维码里包含的错误校验信息增加,相对的图形内容也会越来越密集。
            #endregion
            if (correctionLever == "L")//L水平7%的字码可被修正
             {
                 qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L;
             }
             else if (correctionLever == "M")//M水平15%的字码可被修正
             {
                 qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
             }
             else if (correctionLever == "Q")//Q水平25%的字码可被修正
             {
                 qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.Q;
             }
             else if (correctionLever == "H")//H水平30%的字码可被修正
             {
                 qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H;
             }
             qrCodeEncoder.QRCodeForegroundColor = btnQRCodeForegroundColor.BackColor;//设置二维码前景色
             qrCodeEncoder.QRCodeBackgroundColor = btnQRCodeBackgroundColor.BackColor;//设置二维码背景色

            Image image = qrCodeEncoder.Encode(data, Encoding.UTF8);//生成二维码图片


            if (txtLogo.Text.Trim() != string.Empty)//如果有logo的话则添加logo
            {
                Bitmap btm = new Bitmap(txtLogo.Text);
                Bitmap copyImage = new Bitmap(btm, image.Width / 5, image.Height / 5);
                Graphics g = Graphics.FromImage(image);
                int x = image.Width / 2 - copyImage.Width / 2;
                int y = image.Height / 2 - copyImage.Height / 2;
                g.DrawImage(copyImage, x, y);
            }
            picEncode.Image = image;

        }

        //保存二维码到磁盘
        private void button3_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif|PNG Image|*.png";
            sfd.Title = "保存二维码";
            sfd.FileName = string.Empty;
            if (picEncode.Image != null)
            {
                if (sfd.ShowDialog() == DialogResult.OK && sfd.FileName != "")
                {
                    using (FileStream fs = (FileStream)sfd.OpenFile())
                    {
                        switch (sfd.FilterIndex)
                        {
                            case 1:
                                picEncode.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
                                break;
                            case 2:
                                picEncode.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp);
                                break;
                            case 3:
                                picEncode.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Gif);
                                break;
                            case 4:
                                picEncode.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
                                break;
                        }
                    }
                    MessageBox.Show("保存成功!");
                }
            }
            else
            {
                MessageBox.Show("抱歉,没有要保存的图片!");
            }
        }

        //上传二维码照片
        private void button2_Click(object sender, EventArgs e)
        {
            button8.Visible = true;
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif|PNG Image|*.png";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                String fileName = ofd.FileName;
                picEncode.Image = new Bitmap(fileName);
            }
        }



        //解码
        private void button4_Click(object sender, EventArgs e)
        {
            if(picEncode.Image == null)
            {
                MessageBox.Show("请先上传二维码图片!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                try
                {
                    string decodedString = new QRCodeDecoder().decode(new QRCodeBitmapImage(new Bitmap(picEncode.Image)), Encoding.UTF8);
                    txtData.Text = decodedString;
                }
                catch (Exception)
                {
                    MessageBox.Show("抱歉,无法解码!");
                }
            }  

        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        //上传LOGO
        private void button5_Click(object sender, EventArgs e) 
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif|PNG Image|*.png";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                txtLogo.Text = ofd.FileName;
            }
        }
        //撤销LOGO
        private void button9_Click(object sender, EventArgs e)
        {
            picEncode.Image = null;
            txtLogo.Text = "";
        }

        private void textData_MouseClick(object sender, MouseEventArgs e)
        {
            txtData.Text = "";
        }

        private void label8_Click(object sender, EventArgs e)
        {
            Font f = new Font("Consolas", 14f, FontStyle.Regular);
            label9.Font = f;
            label10.Font = f;
            Font font = new Font("Consolas", 14f, FontStyle.Underline | FontStyle.Italic);
            label8.Font = font;
            label5.Visible = false;
            label6.Visible = false;
            btnQRCodeForegroundColor.Visible = false;
            btnQRCodeBackgroundColor.Visible = false;
            button5.Visible = false;
            txtLogo.Visible = false;
            button9.Visible = false;
            button7.Visible = true;

            button6.Visible = false;
            label1.Visible = true;
            cbEncoding.Visible = true;
            label4.Visible = true;
            cbScale.Visible = true;
            label2.Visible = true;
            cbCorrectionLevel.Visible = true;
            label3.Visible = true;
            label3.Visible = true;
            cbVersion.Visible = true;
        }


        private void label10_Click(object sender, EventArgs e)
        {
            Font f = new Font("Consolas", 14f, FontStyle.Regular);
            label8.Font = f;
            label9.Font = f;
            Font font = new Font("Consolas", 14f, FontStyle.Underline | FontStyle.Italic);
            label10.Font = font;
            label1.Visible = false;
            cbEncoding.Visible = false;
            label4.Visible = false;
            cbScale.Visible = false;
            label2.Visible = false;
            cbCorrectionLevel.Visible = false;
            label3.Visible = false;
            label3.Visible = false;
            cbVersion.Visible = false;
            label5.Visible = false;
            label6.Visible = false;
            btnQRCodeForegroundColor.Visible = false;
            btnQRCodeBackgroundColor.Visible = false;
            button7.Visible = false;

            button6.Visible = false;
            button5.Visible = true;
            txtLogo.Visible = true;
            button9.Visible = true;
        }    

        private void label9_Click(object sender, EventArgs e)
        {
            Font f = new Font("Consolas", 14f, FontStyle.Regular);
            label8.Font = f;
            label10.Font = f;
            Font font = new Font("Consolas", 14f, FontStyle.Underline | FontStyle.Italic);
            label9.Font = font;
            label1.Visible = false;
            cbEncoding.Visible = false;
            label4.Visible = false;
            cbScale.Visible = false;
            label2.Visible = false;
            cbCorrectionLevel.Visible = false;
            label3.Visible = false;
            label3.Visible = false;
            cbVersion.Visible = false;
            button5.Visible = false;
            txtLogo.Visible = false;
            button9.Visible = false;
            button7.Visible = false;

            button6.Visible = true;
            label5.Visible = true;
            label6.Visible = true;
            btnQRCodeForegroundColor.Visible = true;
            btnQRCodeBackgroundColor.Visible = true;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            btnQRCodeForegroundColor.BackColor = System.Drawing.Color.Black;
            btnQRCodeBackgroundColor.BackColor = System.Drawing.Color.White;
        }

        private void button7_Click(object sender, EventArgs e)
        {
            cbVersion.Text = "7";
            cbEncoding.Text = "Byte";
            cbCorrectionLevel.Text = "M";
            cbScale.Text = "5";
        }

        private void button8_Click(object sender, EventArgs e)
        {
            cbVersion.Text = "7";
            cbEncoding.Text = "Byte";
            cbCorrectionLevel.Text = "M";
            cbScale.Text = "5";
            btnQRCodeForegroundColor.BackColor = System.Drawing.Color.Black;
            btnQRCodeBackgroundColor.BackColor = System.Drawing.Color.White;
            txtData.Text = "";
            picEncode.Image = null;
            txtLogo.Text = "";
        }

        private void cbVersion_Click(object sender, EventArgs e)
        {
            MessageBox.Show("请尽量选择5-23范围内的Version值,确保生成的二维码能被准确解读","提示", MessageBoxButtons.OK,MessageBoxIcon.Information);
        }

        private void btnQRCodeBackgroundColor_Click(object sender, EventArgs e)
        {
            colorDialog2.ShowDialog();
            btnQRCodeBackgroundColor.BackColor = colorDialog2.Color;
        }

        private void btnQRCodeForegroundColor_Click(object sender, EventArgs e)
        {
            colorDialog1.ShowDialog();
            btnQRCodeForegroundColor.BackColor = colorDialog1.Color;
        }

        //隐藏textBox控件的竖形指针
        [DllImport("user32.dll")]
        static extern bool HideCaret(IntPtr hWnd);
        private void btnQRCodeBackgroundColor_MouseDown(object sender, MouseEventArgs e)
        {
            HideCaret(btnQRCodeBackgroundColor.Handle);
        }

        private void btnQRCodeForegroundColor_MouseDown(object sender, MouseEventArgs e)
        {
            HideCaret(btnQRCodeForegroundColor.Handle);
        }

        private void btnQRCodeBackgroundColor_MouseUp(object sender, MouseEventArgs e)
        {
            HideCaret(btnQRCodeBackgroundColor.Handle);
        }

        private void btnQRCodeForegroundColor_MouseUp(object sender, MouseEventArgs e)
        {
            HideCaret(btnQRCodeForegroundColor.Handle);
        }
    }

}

效果界面

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值