''' <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