/// <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); }
/// <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 ≤ minVersion ≤ maxVersion ≤ 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); } }
/// <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×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×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×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×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×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); }