Матрица модуляции содержит модуляцию для каждой черной/белой ячейки матрицы штрих-кода и тихой зоны.
Значение модуляции представляет собой число, определенное в диапазоне от -1 до 1:
Вот пример, который демонстрирует как нарисовать матрицу модуляции матричного 2D-штрих-кода (Aztec, DataMatrix, QR, MicroQR и Han Xin Code):
''' <summary> ''' Test that shows how to draw modulation matrix of the matrix 2D barcode ''' (Aztec, DataMatrix, Han Xin Code, QR and MicroQR) on the bitmap. ''' </summary> Class ISO15415QualityTestModulationMatrixExample ''' <summary> ''' Runs the test. ''' </summary> Public Shared Sub Test() ' load image with barcode from file Using barcodeImage As Vintasoft.Imaging.VintasoftBitmap = Vintasoft.Barcode.ImageCodecs.[Default].Decode("testModulationMatrix.jpg") ' read barcodes from image and create the modulation matrix image Dim bitmap As System.Drawing.Bitmap = ReadBarcodesAndCreateModulationMatrixImage(barcodeImage) If bitmap Is Nothing Then Throw New System.Exception() End If bitmap.Save("ModulationMatrix.png") End Using End Sub ''' <summary> ''' Reads barcodes from image, tests the print quality of 2D barcodes and creates the modulation matrix image. ''' </summary> Public Shared Function ReadBarcodesAndCreateModulationMatrixImage(imageWithBarcodes As Vintasoft.Imaging.VintasoftBitmap) As System.Drawing.Bitmap ' create the barcode reader Using reader As New Vintasoft.Barcode.BarcodeReader() ' specify that reader must collect information for barcode print quality test reader.Settings.CollectTestInformation = True ' specify that reader must search for Aztec, DataMatrix, Han Xin Code, QR and MicroQR barcodes only reader.Settings.ScanBarcodeTypes = Vintasoft.Barcode.BarcodeType.Aztec Or Vintasoft.Barcode.BarcodeType.DataMatrix Or Vintasoft.Barcode.BarcodeType.QR Or Vintasoft.Barcode.BarcodeType.MicroQR Or Vintasoft.Barcode.BarcodeType.HanXinCode ' recognize barcodes on image Dim barcodeInfos As Vintasoft.Barcode.IBarcodeInfo() = reader.ReadBarcodes(imageWithBarcodes) ' test print quality of first recognized barcode using ISO 15415 test Dim test As New Vintasoft.Barcode.QualityTests.ISO15415QualityTest() test.CalculateGrades(DirectCast(barcodeInfos(0), Vintasoft.Barcode.BarcodeInfo.BarcodeInfo2D), imageWithBarcodes) ' create modulation matrix image Return CreateModulationMatrixImage(test, 16, 128) End Using End Function ''' <summary> ''' Creates the modulation matrix image. ''' </summary> ''' <param name="qualityTest">The barcode print quality test.</param> ''' <param name="cellSize">The cell size.</param> ''' <param name="modulationAlpha">The modulation alpha.</param> ''' <returns>The bitmap.</returns> Private Shared Function CreateModulationMatrixImage(qualityTest As Vintasoft.Barcode.QualityTests.ISO15415QualityTest, cellSize As Integer, modulationAlpha As Integer) As System.Drawing.Bitmap Dim fontSize As Single = cellSize * 0.35F Dim textFont As System.Drawing.Font = Nothing Dim format As System.Drawing.StringFormat = Nothing If fontSize > 5 Then textFont = New System.Drawing.Font(System.Drawing.SystemFonts.DefaultFont.FontFamily, fontSize) format = New System.Drawing.StringFormat() format.Alignment = System.Drawing.StringAlignment.Center format.LineAlignment = System.Drawing.StringAlignment.Center End If Dim modulationMatrix As Single(,) = qualityTest.ModulationMatrix Dim matrixHeight As Integer = modulationMatrix.GetLength(0) Dim matrixWidth As Integer = modulationMatrix.GetLength(1) ' create bitmap Dim result As New System.Drawing.Bitmap(matrixWidth * cellSize, matrixHeight * cellSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb) ' draw modulation matrix Using foreBrush As New System.Drawing.SolidBrush(System.Drawing.Color.White) Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(result) For y As Integer = 0 To matrixHeight - 1 For x As Integer = 0 To matrixWidth - 1 Dim rect As New System.Drawing.RectangleF(x * cellSize, y * cellSize, cellSize, cellSize) Dim modulation As Single = modulationMatrix(y, x) ' background Dim backBrush As System.Drawing.Brush = If(modulation < 0, System.Drawing.Brushes.White, System.Drawing.Brushes.Black) g.FillRectangle(backBrush, rect) ' modulation highlight foreBrush.Color = System.Drawing.Color.FromArgb(modulationAlpha, GetColor(System.Math.Abs(modulation))) g.FillRectangle(foreBrush, rect) If textFont IsNot Nothing Then ' modulation percent Dim text As String = System.Math.Round(System.Math.Abs(modulation) * 100).ToString() Dim textBrush As System.Drawing.Brush = If(modulation >= 0, System.Drawing.Brushes.White, System.Drawing.Brushes.Black) g.DrawString(text, textFont, textBrush, rect, format) End If Next Next End Using End Using If textFont IsNot Nothing Then textFont.Dispose() End If Return result End Function ''' <summary> ''' Returns the color grade of cell modulation. ''' </summary> ''' <param name="modulation">The cell modulation.</param> ''' <returns>The color.</returns> Private Shared Function GetColor(modulation As Single) As System.Drawing.Color Dim hiColor As System.Drawing.Color = System.Drawing.Color.FromArgb(0, 192, 0) Dim threshold1 As Single = 0.5F Dim threshold1Color As System.Drawing.Color = System.Drawing.Color.FromArgb(128, 192, 0) Dim threshold2 As Single = 0.3F Dim threshold2Color As System.Drawing.Color = System.Drawing.Color.Orange Dim lowColor As System.Drawing.Color = System.Drawing.Color.Red If modulation >= threshold1 Then Return GetInterpolatedColor(threshold1, threshold1Color, 1, hiColor, modulation) End If If modulation >= threshold2 Then Return GetInterpolatedColor(threshold2, threshold2Color, threshold1, threshold1Color, modulation) End If Return GetInterpolatedColor(0, lowColor, threshold2, threshold2Color, modulation) End Function ''' <summary> ''' Returns the interpolated color for specified value. ''' </summary> ''' <param name="min">The minimum value.</param> ''' <param name="minColor">Color for minimum value.</param> ''' <param name="max">The maximum value.</param> ''' <param name="maxColor">Color for maximum value.</param> ''' <param name="value">The value.</param> ''' <returns>The interpolated color for <i>value</i>.</returns> Private Shared Function GetInterpolatedColor(min As Single, minColor As System.Drawing.Color, max As Single, maxColor As System.Drawing.Color, value As Single) As System.Drawing.Color Dim scale As Single = (value - min) / (max - min) Dim r As Single = minColor.R * (1 - scale) + maxColor.R * scale Dim g As Single = minColor.G * (1 - scale) + maxColor.G * scale Dim b As Single = minColor.B * (1 - scale) + maxColor.B * scale Return System.Drawing.Color.FromArgb(CInt(Math.Truncate(System.Math.Round(r))), CInt(Math.Truncate(System.Math.Round(g))), CInt(Math.Truncate(System.Math.Round(b)))) End Function End Class
/// <summary> /// Test that shows how to draw modulation matrix of the matrix 2D barcode /// (Aztec, DataMatrix, Han Xin Code, QR and MicroQR) on the bitmap. /// </summary> class ISO15415QualityTestModulationMatrixExample { /// <summary> /// Runs the test. /// </summary> public static void Test() { // load image with barcode from file using (Vintasoft.Imaging.VintasoftBitmap barcodeImage = Vintasoft.Barcode.ImageCodecs.Default.Decode("testModulationMatrix.jpg")) { // read barcodes from image and create the modulation matrix image System.Drawing.Bitmap bitmap = ReadBarcodesAndCreateModulationMatrixImage(barcodeImage); if (bitmap == null) throw new System.Exception(); bitmap.Save("ModulationMatrix.png"); } } /// <summary> /// Reads barcodes from image, tests the print quality of 2D barcodes and creates the modulation matrix image. /// </summary> public static System.Drawing.Bitmap ReadBarcodesAndCreateModulationMatrixImage(Vintasoft.Imaging.VintasoftBitmap imageWithBarcodes) { // create the barcode reader using (Vintasoft.Barcode.BarcodeReader reader = new Vintasoft.Barcode.BarcodeReader()) { // specify that reader must collect information for barcode print quality test reader.Settings.CollectTestInformation = true; // specify that reader must search for Aztec, DataMatrix, Han Xin Code, QR and MicroQR barcodes only reader.Settings.ScanBarcodeTypes = Vintasoft.Barcode.BarcodeType.Aztec | Vintasoft.Barcode.BarcodeType.DataMatrix | Vintasoft.Barcode.BarcodeType.QR | Vintasoft.Barcode.BarcodeType.MicroQR | Vintasoft.Barcode.BarcodeType.HanXinCode; // recognize barcodes on image Vintasoft.Barcode.IBarcodeInfo[] barcodeInfos = reader.ReadBarcodes(imageWithBarcodes); // test print quality of first recognized barcode using ISO 15415 test Vintasoft.Barcode.QualityTests.ISO15415QualityTest test = new Vintasoft.Barcode.QualityTests.ISO15415QualityTest(); test.CalculateGrades((Vintasoft.Barcode.BarcodeInfo.BarcodeInfo2D)barcodeInfos[0], imageWithBarcodes); // create modulation matrix image return CreateModulationMatrixImage(test, 16, 128); } } /// <summary> /// Creates the modulation matrix image. /// </summary> /// <param name="qualityTest">The barcode print quality test.</param> /// <param name="cellSize">The cell size.</param> /// <param name="modulationAlpha">The modulation alpha.</param> /// <returns>The bitmap.</returns> private static System.Drawing.Bitmap CreateModulationMatrixImage( Vintasoft.Barcode.QualityTests.ISO15415QualityTest qualityTest, int cellSize, int modulationAlpha) { float fontSize = cellSize * 0.35f; System.Drawing.Font textFont = null; System.Drawing.StringFormat format = null; if (fontSize > 5) { textFont = new System.Drawing.Font(System.Drawing.SystemFonts.DefaultFont.FontFamily, fontSize); format = new System.Drawing.StringFormat(); format.Alignment = System.Drawing.StringAlignment.Center; format.LineAlignment = System.Drawing.StringAlignment.Center; } float[,] modulationMatrix = qualityTest.ModulationMatrix; int matrixHeight = modulationMatrix.GetLength(0); int matrixWidth = modulationMatrix.GetLength(1); // create bitmap System.Drawing.Bitmap result = new System.Drawing.Bitmap( matrixWidth * cellSize, matrixHeight * cellSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb); // draw modulation matrix using (System.Drawing.SolidBrush foreBrush = new System.Drawing.SolidBrush(System.Drawing.Color.White)) { using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(result)) { for (int y = 0; y < matrixHeight; y++) { for (int x = 0; x < matrixWidth; x++) { System.Drawing.RectangleF rect = new System.Drawing.RectangleF(x * cellSize, y * cellSize, cellSize, cellSize); float modulation = modulationMatrix[y, x]; // background System.Drawing.Brush backBrush = modulation < 0 ? System.Drawing.Brushes.White : System.Drawing.Brushes.Black; g.FillRectangle(backBrush, rect); // modulation highlight foreBrush.Color = System.Drawing.Color.FromArgb(modulationAlpha, GetColor(System.Math.Abs(modulation))); g.FillRectangle(foreBrush, rect); if (textFont != null) { // modulation percent string text = System.Math.Round(System.Math.Abs(modulation) * 100).ToString(); System.Drawing.Brush textBrush = modulation >= 0 ? System.Drawing.Brushes.White : System.Drawing.Brushes.Black; g.DrawString(text, textFont, textBrush, rect, format); } } } } } if (textFont != null) textFont.Dispose(); return result; } /// <summary> /// Returns the color grade of cell modulation. /// </summary> /// <param name="modulation">The cell modulation.</param> /// <returns>The color.</returns> private static System.Drawing.Color GetColor(float modulation) { System.Drawing.Color hiColor = System.Drawing.Color.FromArgb(0, 192, 0); float threshold1 = 0.5f; System.Drawing.Color threshold1Color = System.Drawing.Color.FromArgb(128, 192, 0); float threshold2 = 0.3f; System.Drawing.Color threshold2Color = System.Drawing.Color.Orange; System.Drawing.Color lowColor = System.Drawing.Color.Red; if (modulation >= threshold1) return GetInterpolatedColor(threshold1, threshold1Color, 1, hiColor, modulation); if (modulation >= threshold2) return GetInterpolatedColor(threshold2, threshold2Color, threshold1, threshold1Color, modulation); return GetInterpolatedColor(0, lowColor, threshold2, threshold2Color, modulation); } /// <summary> /// Returns the interpolated color for specified value. /// </summary> /// <param name="min">The minimum value.</param> /// <param name="minColor">Color for minimum value.</param> /// <param name="max">The maximum value.</param> /// <param name="maxColor">Color for maximum value.</param> /// <param name="value">The value.</param> /// <returns>The interpolated color for <i>value</i>.</returns> private static System.Drawing.Color GetInterpolatedColor(float min, System.Drawing.Color minColor, float max, System.Drawing.Color maxColor, float value) { float scale = (value - min) / (max - min); float r = minColor.R * (1 - scale) + maxColor.R * scale; float g = minColor.G * (1 - scale) + maxColor.G * scale; float b = minColor.B * (1 - scale) + maxColor.B * scale; return System.Drawing.Color.FromArgb((int)System.Math.Round(r), (int)System.Math.Round(g), (int)System.Math.Round(b)); } }
Целевые платформы: .NET 8; .NET 7; .NET 6; .NET Framework 4.8, 4.7, 4.6, 4.5, 4.0, 3.5
ISO15415QualityTest Class
Члены типа ISO15415QualityTest
ModulationGrade
SetQuietZoneSize(BarcodeType,Int32)