C#WinForm二维码编码解码器

来源:互联网 发布:淘宝hd老版本 编辑:程序博客网 时间:2024/06/16 00:55

使用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);        }    }}

效果界面

原创粉丝点击