/// <inheritdoc cref="ToBitmap(QrCode, int, int)"/>
        /// <param name="background">The background color.</param>
        /// <param name="foreground">The foreground color.</param>
        public static SKBitmap ToBitmap(this QrCode qrCode, int scale, int border, SKColor foreground, SKColor background)
        {
            // check arguments
            if (scale <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(scale), "Value out of range");
            }
            if (border < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(border), "Value out of range");
            }

            int size = qrCode.Size;
            int dim  = (size + border * 2) * scale;

            if (dim > short.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(scale), "Scale or border too large");
            }

            // create bitmap
            SKBitmap bitmap = new SKBitmap(dim, dim, SKColorType.Rgb888x, SKAlphaType.Opaque);

            using (SKCanvas canvas = new SKCanvas(bitmap))
            {
                // draw background
                using (SKPaint paint = new SKPaint {
                    Color = background
                })
                {
                    canvas.DrawRect(0, 0, dim, dim, paint);
                }

                // draw modules
                using (SKPaint paint = new SKPaint {
                    Color = foreground
                })
                {
                    for (int y = 0; y < size; y++)
                    {
                        for (int x = 0; x < size; x++)
                        {
                            if (qrCode.GetModule(x, y))
                            {
                                canvas.DrawRect((x + border) * scale, (y + border) * scale, scale, scale, paint);
                            }
                        }
                    }
                }
            }

            return(bitmap);
        }
Пример #2
0
        /// <summary>
        /// Creates a list of zero or more segments to represent the specified text string.
        /// The resulting list optimally minimizes the total encoded bit length, subjected to the constraints
        /// of the specified error correction level, minimum and maximum version number.
        /// <para>
        /// This function potentially uses all four text encoding modes: numeric, alphanumeric, byte (UTF-8),
        /// and Kanji. It is a more sophisticated but slower replacement for <see cref="MakeSegments"/>.
        /// </para>
        /// <para>
        /// The text to be encoded can contain the full set of Unicode characters (code points).
        /// </para>
        /// </summary>
        /// <param name="text">The text to be encoded.</param>
        /// <param name="ecl">The error correction level to use.</param>
        /// <param name="minVersion">The minimum version (size) of the QR code (between 1 and 40).</param>
        /// <param name="maxVersion">The maximum version (size) of the QR code (between 1 and 40).</param>
        /// <returns>The created mutable list of segments encoding the specified text with a minimal bit length.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="text"/> or <paramref name="ecl"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">1 &#x2264; minVersion &#x2264; maxVersion &#x2264; 40 is violated.</exception>
        /// <exception cref="DataTooLongException">The text is too long to fit into the QR code with the given encoding parameters.</exception>
        public static List <QrSegment> MakeSegmentsOptimally(string text, QrCode.Ecc ecl, int minVersion = QrCode.MinVersion, int maxVersion = QrCode.MaxVersion)
        {
            // Check arguments
            Objects.RequireNonNull(text);
            Objects.RequireNonNull(ecl);
            if (minVersion < QrCode.MinVersion || minVersion > maxVersion)
            {
                throw new ArgumentOutOfRangeException(nameof(minVersion), "Invalid value");
            }

            if (maxVersion > QrCode.MaxVersion)
            {
                throw new ArgumentOutOfRangeException(nameof(maxVersion), "Invalid value");
            }

            // Iterate through version numbers, and make tentative segments
            List <QrSegment> segs = null;
            var codePoints        = ToCodePoints(text);

            for (int version = minVersion;; version++)
            {
                if (version == minVersion || version == 10 || version == 27)
                {
                    segs = MakeSegmentsOptimally(codePoints, version);
                }
                Debug.Assert(segs != null);

                // Check if the segments fit
                int dataCapacityBits = QrCode.GetNumDataCodewords(version, ecl) * 8;
                int dataUsedBits     = GetTotalBits(segs, version);
                if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
                {
                    return(segs); // This version number is found to be suitable
                }
                if (version < maxVersion)
                {
                    continue;
                }

                // All versions in the range could not fit the given text
                var msg = "Segment too long";
                if (dataUsedBits != -1)
                {
                    msg = $"Data length = {dataUsedBits} bits, Max capacity = {dataCapacityBits} bits";
                }
                throw new DataTooLongException(msg);
            }
        }
Пример #3
0
        /// <summary>
        /// Creates the <c>QrCode</c> instance with the current settings.
        /// </summary>
        /// <returns></returns>
        private QrCode CreateQrCode()
        {
            QrCode qrCode;
            var    ecc = errorCorrectionLevels[_errorCorrection];

            if (_binaryData != null)
            {
                qrCode = QrCode.EncodeBinary(_binaryData, ecc);
            }
            else
            {
                qrCode = QrCode.EncodeText(_textData, ecc);
            }

            return(qrCode);
        }
        /// <inheritdoc cref="ToBitmap(QrCode, int, int)"/>
        /// <param name="background">The background color.</param>
        /// <param name="foreground">The foreground color.</param>
        public static Image ToBitmap(this QrCode qrCode, int scale, int border, Color foreground, Color background)
        {
            // check arguments
            if (scale <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(scale), "Value out of range");
            }
            if (border < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(border), "Value out of range");
            }

            int size = qrCode.Size;
            int dim  = (size + border * 2) * scale;

            if (dim > short.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(scale), "Scale or border too large");
            }

            // create bitmap
            Image <Rgb24> image = new Image <Rgb24>(dim, dim);

            image.Mutate(img =>
            {
                // draw background
                img.Fill(background);

                // draw modules
                for (int y = 0; y < size; y++)
                {
                    for (int x = 0; x < size; x++)
                    {
                        if (qrCode.GetModule(x, y))
                        {
                            img.Fill(foreground, new Rectangle((x + border) * scale, (y + border) * scale, scale, scale));
                        }
                    }
                }
            });

            return(image);
        }
 /// <summary>
 /// Creates a bitmap (raster image) of this QR code.
 /// <para>
 /// The <paramref name="scale"/> parameter specifies the scale of the image, which is
 /// equivalent to the width and height of each QR code module. Additionally, the number
 /// of modules to add as a border to all four sides can be specified.
 /// </para>
 /// <para>
 /// For example, <c>ToBitmap(scale: 10, border: 4)</c> means to pad the QR code with 4 white
 /// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
 /// </para>
 /// <para>
 /// The resulting bitmap uses the pixel format <see cref="PixelFormat.Format24bppRgb"/>.
 /// If not specified, the foreground color is black (0x000000) und the background color always white (0xFFFFFF).
 /// </para>
 /// </summary>
 /// <param name="scale">The width and height, in pixels, of each module.</param>
 /// <param name="border">The number of border modules to add to each of the four sides.</param>
 /// <returns>The created bitmap representing this QR code.</returns>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
 /// or the resulting image is wider than 32,768 pixels.</exception>
 public static Image ToBitmap(this QrCode qrCode, int scale, int border)
 {
     return(qrCode.ToBitmap(scale, border, Color.Black, Color.White));
 }
 /// <summary>
 /// Saves this QR code as a PNG file.
 /// <para>
 /// The <paramref name="scale"/> parameter specifies the scale of the image, which is
 /// equivalent to the width and height of each QR code module. Additionally, the number
 /// of modules to add as a border to all four sides can be specified.
 /// </para>
 /// <para>
 /// For example, <c>SaveAsPng("qrcode.png", scale: 10, border: 4)</c> means to pad the QR code with 4 white
 /// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
 /// </para>
 /// <para>
 /// If not specified, the foreground color is black (0x000000) und the background color always white (0xFFFFFF).
 /// </para>
 /// </summary>
 /// <param name="scale">The width and height, in pixels, of each module.</param>
 /// <param name="border">The number of border modules to add to each of the four sides.</param>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
 /// or the resulting image is wider than 32,768 pixels.</exception>
 public static void SaveAsPng(this QrCode qrCode, string filename, int scale, int border)
 {
     qrCode.SaveAsPng(filename, scale, border, Color.Black, Color.White);
 }
 /// <inheritdoc cref="SaveAsPng(QrCode, string, int, int)"/>
 /// <param name="background">The background color.</param>
 /// <param name="foreground">The foreground color.</param>
 public static void SaveAsPng(this QrCode qrCode, string filename, int scale, int border, Color foreground, Color background)
 {
     using Image image = qrCode.ToBitmap(scale, border, foreground, background);
     image.SaveAsPng(filename);
 }
 /// <summary>
 /// Creates a PNG image of this QR code and returns it as a byte array.
 /// <para>
 /// The <paramref name="scale"/> parameter specifies the scale of the image, which is
 /// equivalent to the width and height of each QR code module. Additionally, the number
 /// of modules to add as a border to all four sides can be specified.
 /// </para>
 /// <para>
 /// For example, <c>ToPng(scale: 10, border: 4)</c> means to pad the QR code with 4 white
 /// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
 /// </para>
 /// <para>
 /// If not specified, the foreground color is black (0x000000) und the background color always white (0xFFFFFF).
 /// </para>
 /// </summary>
 /// <param name="scale">The width and height, in pixels, of each module.</param>
 /// <param name="border">The number of border modules to add to each of the four sides.</param>
 /// <returns>The created bitmap representing this QR code.</returns>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
 /// or the resulting image is wider than 32,768 pixels.</exception>
 public static byte[] ToPng(this QrCode qrCode, int scale, int border)
 {
     return(qrCode.ToPng(scale, border, Color.Black, Color.White));
 }
 /// <summary>
 /// Creates a bitmap (raster image) of this QR code.
 /// <para>
 /// The <paramref name="scale"/> parameter specifies the scale of the image, which is
 /// equivalent to the width and height of each QR code module. Additionally, the number
 /// of modules to add as a border to all four sides can be specified.
 /// </para>
 /// <para>
 /// For example, <c>ToBitmap(scale: 10, border: 4)</c> means to pad the QR code with 4 white
 /// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
 /// </para>
 /// <para>
 /// The resulting bitmap uses the pixel format <see cref="PixelFormat.Format24bppRgb"/>.
 /// If not specified, the foreground color is black (0x000000) und the background color always white (0xFFFFFF).
 /// </para>
 /// </summary>
 /// <param name="scale">The width and height, in pixels, of each module.</param>
 /// <param name="border">The number of border modules to add to each of the four sides.</param>
 /// <returns>The created bitmap representing this QR code.</returns>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
 /// or the resulting image is wider than 32,768 pixels.</exception>
 public static SKBitmap ToBitmap(this QrCode qrCode, int scale, int border)
 {
     return(qrCode.ToBitmap(scale, border, SKColors.Black, SKColors.White));
 }
 /// <inheritdoc cref="ToPng(QrCode, int, int)"/>
 /// <param name="background">The background color.</param>
 /// <param name="foreground">The foreground color.</param>
 public static byte[] ToPng(this QrCode qrCode, int scale, int border, SKColor foreground, SKColor background)
 {
     using SKBitmap bitmap = qrCode.ToBitmap(scale, border, foreground, background);
     using SKData data     = bitmap.Encode(SKEncodedImageFormat.Png, 90);
     return(data.ToArray());
 }
 /// <inheritdoc cref="SaveAsPng(QrCode, string, int, int)"/>
 /// <param name="background">The background color.</param>
 /// <param name="foreground">The foreground color.</param>
 public static void SaveAsPng(this QrCode qrCode, string filename, int scale, int border, Color foreground, Color background)
 {
     using Bitmap bitmap = qrCode.ToBitmap(scale, border, foreground, background);
     bitmap.Save(filename, ImageFormat.Png);
 }
 /// <summary>
 /// Draws this QR code into the specified graphics context.
 /// <para>
 /// The QR code is drawn at offset (0, 0). Use <see cref="Graphics.TranslateTransform(float, float)"/>
 /// to draw it at a different position.
 /// </para>
 /// <para>
 /// The <paramref name="scale"/> parameter specifies the scale of the image, which is
 /// equivalent to the width and height of each QR code module. Additionally, the number
 /// of modules to add as a border to all four sides can be specified.
 /// </para>
 /// <para>
 /// For example, <c>Draw(graphics, scale: 10, border: 4)</c> means to pad the QR code with 4 white
 /// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
 /// </para>
 /// <para>
 /// </summary>
 /// <param name="graphics">The graphics context to draw in.</param>
 /// <param name="scale">The width and height, in pixels, of each module.</param>
 /// <param name="border">The number of border modules to add to each of the four sides.</param>
 public static void Draw(this QrCode qrCode, Graphics graphics, float scale, float border)
 {
     Draw(qrCode, graphics, scale, border, Color.Black, Color.White);
 }