/// <summary> /// Generates a QR code with the automatically defined version and specified error correction level, pixel scaling, color, background color, and quiet zone from the input data and returns the QR code image as an array of bytes. /// </summary> /// <param name="data">The user data for encoding.</param> /// <param name="encoding">The QR code encoding.</param> /// <param name="levelCorrection">The level of error correction.</param> /// <param name="scaleMultiplier">The pixel scaling of the resulting QR code image.</param> /// <param name="foregroundColor">The QR code color.</param> /// <param name="backgroundColor">The background color.</param> /// <param name="hasQuietZones">Defines whether the QR code has a "quiet zone".</param> /// <returns>byte[]</returns> public static byte[] GetQRCode(string data, QRCodeEncodingMethod encoding, QRCodeErrorCorrection levelCorrection, int scaleMultiplier, Color foregroundColor, Color backgroundColor, bool hasQuietZones = true) { return(GetQRCode(data, encoding, levelCorrection, QRCodesUtils.GetMinVersionForBinaryMode(data, levelCorrection), scaleMultiplier, foregroundColor, backgroundColor, hasQuietZones)); }
private static void SaveByteToBitArray(ref BitArray arr, byte data, int countBits = 8) { byte mask = (byte)(1 << (countBits - 1)); for (int i = 0; i < countBits; i++) { arr = QRCodesUtils.LeftShift(arr, 1); arr[0] = (data & mask) != 0 ? true : false; data <<= 1; } }
/// <summary> /// Creates a QR code in the binary encoding. /// </summary> /// <param name="data">The user data for encoding.</param> /// <param name="version">The QR code version.</param> /// <param name="levelCorrection">The level of error correction.</param> /// <returns>byte[]</returns> public static byte[] EncodeQRCodeData(string data, int version, QRCodeErrorCorrection levelCorrection) { BitArray arrData; UTF8Encoding utf8 = new UTF8Encoding(); var arrBytes = utf8.GetBytes(data); byte codeMethod = MethodCode(QRCodeEncodingMethod.Binary); int lengthStandard = QRCodesData.QRCodeMaxLengths[version - 1][(int)levelCorrection]; arrData = new BitArray(lengthStandard); int bitsSaved = 0; // Write the header if (version < 10) { SaveByteToBitArray(ref arrData, codeMethod, 4); SaveByteToBitArray(ref arrData, (byte)arrBytes.Length); bitsSaved += 12; } else { SaveByteToBitArray(ref arrData, codeMethod, 4); SaveByteToBitArray(ref arrData, (byte)((arrBytes.Length >> 8) & 0xFF)); SaveByteToBitArray(ref arrData, (byte)(arrBytes.Length & 0xFF)); bitsSaved += 20; } // No space for data error if ((arrBytes.Length << 3) + bitsSaved + (bitsSaved % 8) > lengthStandard) { throw new InvalidOperationException(); } // Write the data foreach (var byteData in arrBytes) { SaveByteToBitArray(ref arrData, byteData); } // Align to full bytes size bitsSaved += arrBytes.Length << 3; int bitsTail = bitsSaved % 8; arrData = QRCodesUtils.LeftShift(arrData, bitsTail); AlignToFullSize(ref arrData, bitsSaved + bitsTail, lengthStandard); int countBlocks = QRCodesData.QRCodeBlockCounts[version - 1][(int)levelCorrection]; var lengthBlocks = GetLengthOfBlocks(lengthStandard, countBlocks); // Split the data into blocks var dataBlocks = GetBlocks(lengthBlocks, arrData); var countCorrection = QRCodesData.QRCodeCorrectionCounts[version - 1][(int)levelCorrection]; byte[] kCorrection = QRCodesData.QRCodeCorrectionK[(byte)countCorrection]; // Add correction codes to the blocks and return results return(AddCorrectionCodeToBlocks(dataBlocks, countCorrection, kCorrection)); }
public void TestGetMinVersionOfQRCodeForBinaryMode() { QRCodesUtils.GetMinVersionForBinaryMode("test", QRCodeErrorCorrection.M) .Should().Be(1); QRCodesUtils.GetMinVersionForBinaryMode(string.Concat(Enumerable.Repeat("test ", 12)), QRCodeErrorCorrection.Q) .Should().Be(5); QRCodesUtils.GetMinVersionForBinaryMode(string.Concat(Enumerable.Repeat("test ", 12)), QRCodeErrorCorrection.H) .Should().Be(7); Assert.Throws <InvalidOperationException>(() => QRCodesUtils.GetMinVersionForBinaryMode(string.Concat(Enumerable.Repeat("test ", 10000)), QRCodeErrorCorrection.L)); }
/// <summary> /// Renders a QR code on bitmap from the encoded data and returns an array of bytes. /// </summary> /// <param name="data">The user data for encoding.</param> /// <param name="encoding">The QR code encoding.</param> /// <param name="levelCorrection">The level of error correction.</param> /// <param name="version">The QR code version.</param> /// <param name="scaleMultiplier">The pixel scaling of the resulting QR code image.</param> /// <param name="foregroundColor">The QR code color.</param> /// <param name="backgroundColor">The background color.</param> /// <param name="quietZone">The size of the quiet zone.</param> /// <returns>byte[]</returns> internal static byte[] GetQRCodeImage(string data, QRCodeEncodingMethod encoding, QRCodeErrorCorrection levelCorrection, QRCodeVersion version, int scaleMultiplier, Color foregroundColor, Color backgroundColor, int quietZone = 4) { if (!Enum.IsDefined(typeof(QRCodeVersion), version)) { throw new ArgumentOutOfRangeException(); } // Only the binary method is implemented if (encoding != QRCodeEncodingMethod.Binary) { throw new NotImplementedException(); } int numVersion; if (version == QRCodeVersion.Automatic) { numVersion = (int)QRCodesUtils.GetMinVersionForBinaryMode(data, levelCorrection); } else { numVersion = (int)version; } var numberMask = 4; // Get the image data array byte[] dataBinary = QRCodesEncoder.EncodeQRCodeData(data, numVersion, levelCorrection); // Create a bitmap for the QR code var bitmapSource = CreateBitmap(dataBinary, numVersion, numberMask, levelCorrection, new SolidBrush(foregroundColor), new SolidBrush(backgroundColor), quietZone); // Pixel scaling var bitmap = QRCodesUtils.Scale(bitmapSource, scaleMultiplier); // Save the resulting image in the PNG format var memStream = new MemoryStream(); bitmap.Save(memStream, System.Drawing.Imaging.ImageFormat.Png); memStream.Flush(); var qrData = memStream.ToArray(); memStream.Close(); return(qrData); }
public void TestInputParamsValidation_GetMinVersionOfQRCodeForBinaryMode(string text, int correction, bool shouldThrowArgumentException, string caseName) { if (shouldThrowArgumentException) { ((Action)call).Should().ThrowExactly <ArgumentException>(); } else { call(); } Assert.True(true, caseName); void call() { QRCodesUtils.GetMinVersionForBinaryMode(text, (QRCodeErrorCorrection)correction); } }