VintaSoft Barcode .NET SDK 14.3: 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; }
    
    
    public: __property float[,] get_ModulationMatrix();
    
    
    
    public:
    property float[,] ModulationMatrix { float[,] 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 -1..1:

    • range [-1..0) - modulation of white cell, -1 value indicates 100% modulation
    • range (0..1] - 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 8; .NET 7; .NET 6; .NET Framework 4.8, 4.7, 4.6, 4.5, 4.0, 3.5

    See Also