VintaSoft Barcode .NET SDK 16.0: Documentation for .NET developer
Vintasoft.Barcode.QualityTests Namespace / ISO15415QualityTest Class / ModulationMatrix Property
Syntax Remarks Example Requirements SeeAlso
In This Topic
ModulationMatrix Property (ISO15415QualityTest)
In This Topic
Gets the matrix that contains cells modulation of a matrix barcode.
Syntax
'Declaration

Public ReadOnly Property ModulationMatrix As Single[,]

public float[,] ModulationMatrix { get; }

Remarks

The modulation matrix contains the modulation for each black/white cell of barcode matrix and quiet zone.
The modulation value is a number defined in range from -1 to 1:

  • range from -1 to 0 (except 0) - modulation of white cell, -1 value indicates 100% modulation
  • range from 0 to 1 (except 0) - modulation of black cell, 1 value indicates 100% modulation

Example

Here is an example that demonstrates how to draw modulation matrix of the matrix 2D barcode (Aztec, DataMatrix, QR, MicroQR and 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));
    }


}

Requirements

Target Platforms: .NET 10; .NET 9; .NET 8; .NET 7; .NET 6; .NET Framework 4.8, 4.7, 4.6, 4.5, 4.0, 3.5

See Also