Laden...

QR-Code Generator

Erstellt von TheBrainiac vor 11 Jahren Letzter Beitrag vor 8 Jahren 32.209 Views
TheBrainiac Themenstarter:in
795 Beiträge seit 2006
vor 11 Jahren
QR-Code Generator

Beschreibung:

Da ich in meinem aktuellen Projekt viele QRCodes generieren muss und mir die bei Google zu findenden Komponenten zu kompliziert bzw. buggy waren, hab ich mir selbst eine Komponente geschrieben. Diese basiert auf der Google-Charts-API.

Die Verwendung ist denkbar einfach:

myImage.Image = QRCode.Generate("Das Pferd frisst keinen Gurkensalat");

Da ich die einzelnen Methoden dokumentiert habe, werde ich hier nicht weiter auf diese eingehen.

Weiterhin muss ich QRCodes auf Etiketten drucken, also habe ich mir dafür auch extra Methoden geschrieben.

var ids = new Guid[5, 5];

for (int x = 0; x < 5; x++)
{
    for (int y = 0; y < 5; y++)
    {
        ids[x, y] = Guid.NewGuid();
    }
}

imageToBePrinted = QRCode.GenerateMany(ids);

Das hat das angehängte Bild zum Resultat (ohne den grauen Bereich).

using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Net;
using System.Web;

namespace QRCodes
{
    /// <summary>
    /// Class providing methods for generating QR BarCodes.
    /// </summary>
    public static class QRCode
    {
        private static readonly WebClient m_WebClient = new WebClient();

        private const string m_GoogleApiUrl = "http://chart.apis.google.com/chart?cht=qr&chld={2}|{3}&chs={0}x{0}&chl={1}";
        private const int m_GuidCodeSize = 31;

        private static int m_DefaultSize = 80;
        private static int m_DefaultMargin = 0;
        private static int m_DefaultGuidScale = 2;
        private static int m_DefaultManyMargin = 5;
        private static ErrorCorrectionLevel m_DefaultErrorCorrection = ErrorCorrectionLevel.Low;

        /// <summary>
        /// Gets or sets the default margin between QR BarCodes in images containing many of them.
        /// </summary>
        /// <value>
        /// The default margin between QR BarCodes in images containing many of them.
        /// </value>
        public static int DefaultManyMargin
        {
            get { return m_DefaultManyMargin; }
            set { m_DefaultManyMargin = value; }
        }

        /// <summary>
        /// Gets or sets the default GUID scale.
        /// </summary>
        /// <value>
        /// The default GUID scale.
        /// </value>
        public static int DefaultGuidScale
        {
            get { return m_DefaultGuidScale; }
            set { m_DefaultGuidScale = value; }
        }

        /// <summary>
        /// Gets or sets the default size.
        /// </summary>
        /// <value>
        /// The default size.
        /// </value>
        public static int DefaultSize
        {
            get { return m_DefaultSize; }
            set { m_DefaultSize = value; }
        }

        /// <summary>
        /// Gets or sets the default margin.
        /// </summary>
        /// <value>
        /// The default margin.
        /// </value>
        public static int DefaultMargin
        {
            get { return m_DefaultMargin; }
            set { m_DefaultMargin = value; }
        }

        /// <summary>
        /// Gets or sets the default error correction Level.
        /// </summary>
        /// <value>
        /// The default error correction level.
        /// </value>
        public static ErrorCorrectionLevel DefaultErrorCorrection
        {
            get { return m_DefaultErrorCorrection; }
            set { m_DefaultErrorCorrection = value; }
        }

        /// <summary>
        /// Generates an QR BarCode containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <returns>The image containing the generated QR BarCode.</returns>
        public static Image Generate(Guid data)
        {
            if (data == null) throw new ArgumentNullException("data");

            return Generate(data, m_DefaultGuidScale);
        }

        /// <summary>
        /// Generates an QR BarCode containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <param name="scale">The scale of the QR BarCode.</param>
        /// <returns>The image containing the generated QR BarCode.</returns>
        public static Image Generate(Guid data, int scale)
        {
            if (data == null) throw new ArgumentNullException("data");
            if (scale < 1) throw new ArgumentOutOfRangeException("scale", scale, "Must be greater than zero.");

            return Generate(data.ToString("N"), m_GuidCodeSize * scale, 1, ErrorCorrectionLevel.Medium);
        }

        /// <summary>
        /// Generates an image containing the QR BarCodes containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <returns>The image containing the generated QR BarCodes.</returns>
        public static Image GenerateMany(Guid[,] data)
        {
            if (data == null) throw new ArgumentNullException("data");

            return GenerateMany(data, m_DefaultManyMargin, m_DefaultGuidScale);
        }

        /// <summary>
        /// Generates an image containing the QR BarCodes containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <param name="manyMargin">The margin between the BarCodes.</param>
        /// <param name="scale">The scale of the QR BarCode.</param>
        /// <returns>The image containing the generated QR BarCodes.</returns>
        public static Image GenerateMany(Guid[,] data, int manyMargin, int scale)
        {
            if (data == null) throw new ArgumentNullException("data");
            if (manyMargin < 0) throw new ArgumentOutOfRangeException("manyMargin", manyMargin, "Must be greater than or equal to zero.");
            if (scale < 1) throw new ArgumentOutOfRangeException("scale", scale, "Must be greater than zero.");

            var countX = data.GetLength(0);
            var countY = data.GetLength(1);
            var img = new Bitmap(m_GuidCodeSize * scale * countX + manyMargin * (countX + 1), m_GuidCodeSize * scale * countY + manyMargin * (countY + 1));

            using (var g = Graphics.FromImage(img))
            {
                g.Clear(Color.White);

                for (int x = 0; x < countX; x++)
                {
                    for (int y = 0; y < countY; y++)
                    {
                        using (var qr = QRCode.Generate(data[x, y], scale))
                        {
                            var loc = new Point(x * qr.Width + manyMargin * x + manyMargin, y * qr.Height + manyMargin * y + manyMargin);

                            g.DrawImage(qr, loc);
                            g.DrawRectangle(Pens.Black, new Rectangle(new Point(loc.X - 1, loc.Y - 1), new Size(qr.Width + 1, qr.Height + 1)));
                        }
                    }
                }
            }

            return img;
        }

        /// <summary>
        /// Generates an QR BarCode containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <returns>The image containing the generated QR BarCode.</returns>
        public static Image Generate(string data)
        {
            if (data == null) throw new ArgumentNullException("data");

            return Generate(data, m_DefaultSize, m_DefaultMargin, m_DefaultErrorCorrection);
        }

        /// <summary>
        /// Generates an QR BarCode containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <param name="size">Image size.</param>
        /// <param name="margin">The width of the white border around the data portion of the code. This is in rows, not in pixels.</param>
        /// <param name="errorCorrection">QR codes support four levels of error correction to enable recovery of missing, misread, or obscured data. Greater redundancy is achieved at the cost of being able to store less data.</param>
        /// <returns>The image containing the generated QR BarCode.</returns>
        public static Image Generate(string data, int size, int margin, ErrorCorrectionLevel errorCorrection)
        {
            if (data == null) throw new ArgumentNullException("data");
            if (size < 1) throw new ArgumentOutOfRangeException("size", size, "Must be greater than zero.");
            if (margin < 0) throw new ArgumentOutOfRangeException("margin", margin, "Must be greater than or equal to zero.");
            if (!Enum.IsDefined(typeof(ErrorCorrectionLevel), errorCorrection)) throw new InvalidEnumArgumentException("errorCorrectionLevel", (int)errorCorrection, typeof(ErrorCorrectionLevel));

            var link = string.Format(m_GoogleApiUrl, size, HttpUtility.UrlEncode(data), errorCorrection.ToString()[0], margin);

            using (var ms = new MemoryStream(m_WebClient.DownloadData(link)))
            {
                return Image.FromStream(ms);
            }
        }

        /// <summary>
        /// Generates an image containing the QR BarCodes containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <returns>The image containing the generated QR BarCodes.</returns>
        public static Image GenerateMany(string[,] data)
        {
            if (data == null) throw new ArgumentNullException("data");

            return GenerateMany(data, m_DefaultSize, m_DefaultManyMargin, m_DefaultMargin, m_DefaultErrorCorrection);
        }

        /// <summary>
        /// Generates an image containing the QR BarCodes containing the specified data.
        /// </summary>
        /// <param name="data">The data to encode.</param>
        /// <param name="size">Image size.</param>
        /// <param name="manyMargin">The margin between the BarCodes.</param>
        /// <param name="margin">The width of the white border around the data portion of the code. This is in rows, not in pixels.</param>
        /// <param name="errorCorrection">QR codes support four levels of error correction to enable recovery of missing, misread, or obscured data. Greater redundancy is achieved at the cost of being able to store less data.</param>
        /// <returns>The image containing the generated QR BarCodes.</returns>
        public static Image GenerateMany(string[,] data, int size, int manyMargin, int margin, ErrorCorrectionLevel errorCorrection)
        {
            if (data == null) throw new ArgumentNullException("data");
            if (size < 1) throw new ArgumentOutOfRangeException("size", size, "Must be greater than zero.");
            if (margin < 0) throw new ArgumentOutOfRangeException("margin", margin, "Must be greater than or equal to zero.");
            if (manyMargin < 0) throw new ArgumentOutOfRangeException("manyMargin", manyMargin, "Must be greater than or equal to zero.");
            if (!Enum.IsDefined(typeof(ErrorCorrectionLevel), errorCorrection)) throw new InvalidEnumArgumentException("errorCorrectionLevel", (int)errorCorrection, typeof(ErrorCorrectionLevel));

            var countX = data.GetLength(0);
            var countY = data.GetLength(1);
            var img = new Bitmap(size * countX + manyMargin * (countX + 1), size * countY + manyMargin * (countY + 1));

            using (var g = Graphics.FromImage(img))
            {
                g.Clear(Color.White);

                for (int x = 0; x < countX; x++)
                {
                    for (int y = 0; y < countY; y++)
                    {
                        using (var qr = QRCode.Generate(data[x, y], size, margin, errorCorrection))
                        {
                            var loc = new Point(x * qr.Width + manyMargin * x + manyMargin, y * qr.Height + manyMargin * y + manyMargin);

                            g.DrawImage(qr, loc);
                            g.DrawRectangle(Pens.Black, new Rectangle(loc, new Size(qr.Width - 1, qr.Height - 1)));
                        }
                    }
                }
            }

            return img;
        }
    }

    /// <summary>
    /// QR codes support four levels of error correction to enable recovery of missing, misread, or obscured data.
    /// Greater redundancy is achieved at the cost of being able to store less data.
    /// </summary>
    public enum ErrorCorrectionLevel
    {
        /// <summary>
        /// [Default] Allows recovery of up to 7% data loss
        /// </summary>
        Low = 0,
        /// <summary>
        /// Allows recovery of up to 15% data loss
        /// </summary>
        Medium,
        /// <summary>
        /// Allows recovery of up to 25% data loss
        /// </summary>
        QuiteGood,
        /// <summary>
        /// Allows recovery of up to 30% data loss
        /// </summary>
        High
    }
}

Gruß, Christian.

Schlagwörter: QR Code Generator

`There are 10 types of people in the world: Those, who think they understand the binary system Those who don't even have heard about it And those who understand "Every base is base 10"`
2.891 Beiträge seit 2004
vor 11 Jahren

Diese basiert auf der Google-Charts-API.

Gibt es da irgendwelche Beschränkungen oder kann man die frei und beliebig oft nutzen?

T
708 Beiträge seit 2008
vor 11 Jahren

Hallo zusammen,

vor einigen Tagen habe ich eine ziemlich umfangreiche Komponente bei CodeProject gefunden.
Vielleicht gibt es dort ja ein paar Anregungen für eine mögliche Offlinelösung.
QrCode.Net

Bisher habe ich nur etwas damit herumgespielt. Funktioniert aber soweit ganz gut!

Gruß,
trib

TheBrainiac Themenstarter:in
795 Beiträge seit 2006
vor 11 Jahren

Gibt es da irgendwelche Beschränkungen oder kann man die frei und beliebig oft nutzen?

Laut Google Developers: Getting Started with Infographics nicht:

There's no limit to the number of requests per day you can make for infographics. However, we reserve the right to block any use that we regard as abusive.

Gruß, Christian.

`There are 10 types of people in the world: Those, who think they understand the binary system Those who don't even have heard about it And those who understand "Every base is base 10"`
M
8 Beiträge seit 2006
vor 11 Jahren
B
293 Beiträge seit 2008
vor 8 Jahren

Alternativ hätte ich auch noch folgende Offline-Variante im Angebot. Ist noch etwas einfacher zu benutzen als die Variante von Scott Hanselman. Die Library steht zudem unter der MIT-Lizenz.

QRCoder - C# QR-Code-Generator

Wenn ich nicht hier bin, findest du mich auf code-bude.net.

37 Beiträge seit 2014
vor 8 Jahren

Hi,

war ZXing keine Alternative?
=> https://zxingnet.codeplex.com

Hätte ich zwar noch nicht oft verwendet, aber bisher keine Probleme damit gehabt. Und läuft natürlich auch Offline.

16.807 Beiträge seit 2008
vor 8 Jahren

ZXIng kann ich empfehlen.
Hab ich für meine Zwei-Faktor-Auth-Bibliothek für NuGet verwendet - einwandfrei.