예제 #1
0
        internal static float GetPercentToCut(float height, MeasureBarcodeUnit heightToCut, int scaleMultiplier)
        {
            switch (heightToCut.Type)
            {
            case MeasureBarcodeType.Percent:
            {
                if (heightToCut.Value > 99)
                {
                    throw new InvalidOperationException("Cannot cut more than 99% of height.");
                }
                return(heightToCut.Value);
            }

            case MeasureBarcodeType.Pixel:
            {
                float percent = GetPercent(height, heightToCut.Value * scaleMultiplier);
                if (percent > 99)
                {
                    throw new InvalidOperationException("Cannot cut more than 99% of height.");
                }
                return(percent);
            }

            default:
                throw new InvalidOperationException("Parameter cutHeight must be of type Pixel or Percent.");
            }
        }
예제 #2
0
        /// <summary>
        /// Renders a GS1-128 barcode on bitmap from the encoded data.
        /// </summary>
        /// <param name="encodedData">The encoded data.</param>
        /// <param name="textDataString">The text to be printed under the barcode lines.</param>
        /// <param name="heightToCut">The height in pixels or in percent to be cut from the top of the barcode lines. Can be 0.</param>
        /// <param name="showDataLabel">Defines whether to print the barcode data under the lines.</param>
        /// <param name="scaleMultiplier">The multiplier of the barcode width for better text rendering.</param>
        /// <param name="backColor">The background color.</param>
        /// <param name="hasQuietZones">Defines whether the barcode has quiet zones.</param>
        /// <param name="strokeColor">The color of barcode lines.</param>
        /// <param name="barcodeRotation">Defines barcode rotation angle.</param>
        /// <returns></returns>
        internal static byte[] GetBarcodeImageGS1_128(byte[] encodedData, string textDataString,
                                                      MeasureBarcodeUnit heightToCut, bool showDataLabel = true, int scaleMultiplier = 2,
                                                      Color?strokeColor = null, Color?backColor = null, bool hasQuietZones = true, BarcodeRotation barcodeRotation = BarcodeRotation.Clockwise_0)
        {
            // Draw barcode on bitmap:
            Bitmap bitmap = DrawBitmapGS1_128(encodedData, textDataString, heightToCut, showDataLabel, scaleMultiplier, strokeColor, backColor, hasQuietZones, barcodeRotation);

            // Save bitmap to a byte array:
            using (var memStream = new MemoryStream())
            {
                bitmap.Save(memStream, ImageFormat.Png);
                return(memStream.ToArray());
            }
        }
예제 #3
0
        internal static float GetPixels(float from, MeasureBarcodeUnit howMuch)
        {
            switch (howMuch.Type)
            {
            case MeasureBarcodeType.Percent:
                return(from * howMuch.Value / 100);

            case MeasureBarcodeType.Pixel:
                return(howMuch.Value);

            default:
                throw new System.InvalidOperationException("Parameter cutHeight must be of type Pixel or Percent");
            }
        }
        public void Test_MeasureBarcodeUnit(MeasureBarcodeType heightType, float heightValue, string caseName)
        {
            MeasureBarcodeUnit height = new MeasureBarcodeUnit(0);

            if (heightType == MeasureBarcodeType.Percent)
            {
                height = MeasureBarcodeUnit.FromPercent(heightValue);
            }
            else if (heightType == MeasureBarcodeType.Pixel)
            {
                height = MeasureBarcodeUnit.FromPixel(heightValue);
            }
            height.Type.Should().Be(heightType);
            height.Value.Should().Be(heightValue);
        }
예제 #5
0
 internal static void ValidateInputParameters(MeasureBarcodeUnit heightToCut, int scaleMultiplier)
 {
     if ((heightToCut.Type == MeasureBarcodeType.Percent) && (heightToCut.Value > 99))
     {
         throw new System.InvalidOperationException("Cannot cut more than 99% of barcode height.");
     }
     if ((heightToCut.Type == MeasureBarcodeType.Percent) && (heightToCut.Value < 0))
     {
         throw new System.InvalidOperationException("Height to cut cannot be negative.");
     }
     if (scaleMultiplier < 1)
     {
         throw new System.InvalidOperationException("scaleMultiplier cannot be less than 1.");
     }
 }
        public void QuickStart_BarcodeGS128()
        {
            byte[] dataBarcodeGS128 = BarcodesMaker.GetBarcode("012345678912ABCD",
                                                               BarcodeType.GS1_128A,
                                                               Color.Black,
                                                               Color.White,
                                                               true,
                                                               MeasureBarcodeUnit.FromPixel(0));
            using (Image image = Image.FromStream(new MemoryStream(dataBarcodeGS128)))
            {
                image.Save("barcodeGS128.png", System.Drawing.Imaging.ImageFormat.Png);
            }

            FileComparer.AreEqual("etalon_barcodeGS128.png", "barcodeGS128.png").Should().Be(true);
        }
        public void QuickStart_BarcodeEAN13_Colors_NoQuiteZones()
        {
            byte[] dataBarcode13 = BarcodesMaker.GetBarcode("0123456789123",
                                                            BarcodeType.EAN_13,
                                                            Color.Green,
                                                            Color.White,
                                                            true,
                                                            MeasureBarcodeUnit.FromPixel(0),
                                                            2,
                                                            false);
            using (Image image = Image.FromStream(new MemoryStream(dataBarcode13)))
            {
                image.Save("barcodeEAN13_2.png", System.Drawing.Imaging.ImageFormat.Png);
            }

            FileComparer.AreEqual("etalon_barcodeEAN13_2.png", "barcodeEAN13_2.png").Should().Be(true);
        }
        public void Test_ValidationOfInputParameters(MeasureBarcodeType heightToCutType, float heightToCutValue, bool shouldFail, string because)
        {
            void Validate()
            {
                MeasureBarcodeUnit heightToCut = new MeasureBarcodeUnit(heightToCutValue, heightToCutType);

                BarcodesUtils.ValidateInputParameters(heightToCut, 4);
            }

            if (shouldFail)
            {
                ((Action)Validate).Should().ThrowExactly <InvalidOperationException>();
            }
            else
            {
                Validate();
            }
        }
예제 #9
0
        /// <summary>
        /// Generates a GS1-128 barcode image from the input data and returns the image as an array of bytes.
        /// </summary>
        /// <param name="data">The input data for the barcode.</param>
        /// <param name="barcodeType">The barcode type.</param>
        /// <param name="lineColor">The color of barcode lines.</param>
        /// <param name="backColor">The background color.</param>
        /// <param name="showDataLabel">Defines whether the input data is printed under the barcode lines.</param>
        /// <param name="heightToCut">The height in pixels or in percent to be cut from the top of the barcode lines to reduce the standard height.</param>
        /// <param name="scaleMultiplier">The multiplier of the barcode width for better text rendering.</param>
        /// <param name="hasQuietZones">Defines whether the barcode has quiet zones.</param>
        /// <param name="barcodeRotation">Defines barcode rotation angle.</param>
        /// <returns>Array of bytes</returns>

        internal static byte[] GetBarcodeGS1_128(string data, BarcodeType barcodeType, System.Drawing.Color lineColor, System.Drawing.Color backColor, bool showDataLabel, MeasureBarcodeUnit heightToCut, int scaleMultiplier = 2, bool hasQuietZones = true, BarcodeRotation barcodeRotation = BarcodeRotation.Clockwise_0)
        {
            // Process the data and encode it:
            byte[] encodedData = BarcodesEncoder.EncodeBarcodeDataGS1_128(data, barcodeType);

            // Create an image using encodedData and save the image to a byte array:
            byte[] imgData = BarcodesRenderer.GetBarcodeImageGS1_128(encodedData, data, heightToCut, showDataLabel, scaleMultiplier, strokeColor: lineColor, backColor: backColor, hasQuietZones, barcodeRotation);
            return(imgData);
        }
예제 #10
0
        /// <summary>
        /// Generates a barcode image from the input data and returns the image as an array of bytes.
        /// </summary>
        /// <param name="data">The input data for the barcode.</param>
        /// <param name="barcodeType">The barcode type.</param>
        /// <param name="lineColor">The color of barcode lines.</param>
        /// <param name="backColor">The background color.</param>
        /// <param name="showDataLabel">Defines whether the input data is printed under the barcode lines.</param>
        /// <param name="heightToCut">The height in pixels or in percent to be cut from the top of the barcode lines to reduce the standard height.</param>
        /// <param name="scaleMultiplier">The multiplier of the barcode width for better text rendering.</param>
        /// <param name="hasQuietZones">Defines whether the barcode has quiet zones.</param>
        /// <param name="barcodeRotation">Defines barcode rotation angle.</param>
        /// <returns>Array of bytes</returns>
        public static byte[] GetBarcode(string data, BarcodeType barcodeType, System.Drawing.Color lineColor, System.Drawing.Color backColor, bool showDataLabel, MeasureBarcodeUnit heightToCut, int scaleMultiplier = 2, bool hasQuietZones = true, BarcodeRotation barcodeRotation = BarcodeRotation.Clockwise_0)
        {
            // Validate the data depending on barcodeType:
            BarcodesUtils.ValidateBarcodeData(data, barcodeType);

            // Validate the input parameters:
            BarcodesUtils.ValidateInputParameters(heightToCut, scaleMultiplier);

            if (barcodeType == BarcodeType.EAN_8 || barcodeType == BarcodeType.EAN_13 || barcodeType == BarcodeType.UPC_A)
            {
                byte[] imgData = GetBarcodeEAN_UPC(data, barcodeType, lineColor, backColor, showDataLabel, heightToCut, scaleMultiplier, hasQuietZones, barcodeRotation);
                return(imgData);
            }
            else
            {
                byte[] imgData = GetBarcodeGS1_128(data, barcodeType, lineColor, backColor, showDataLabel, heightToCut, scaleMultiplier, hasQuietZones, barcodeRotation);
                return(imgData);
            }
        }
        public void Test_Renderer_GS1_128(BarcodeType type, MeasureBarcodeType heightToCutType, float heightToCutValue, int scaleMultiplier, bool hasQuiteZones, bool rotate270, string caseName)
        {
            MeasureBarcodeUnit heightToCut = new MeasureBarcodeUnit(heightToCutValue, heightToCutType);
            float labelHeight = scaleMultiplier * 2;
            int   widthShould;
            Font  labelFont = new Font(GS1_128Data.font_family_name, GS1_128Data.default_font_size * scaleMultiplier);

            labelHeight += labelFont.Size;
            BarcodeRotation rotation = BarcodeRotation.Clockwise_0;

            if (rotate270)
            {
                rotation = BarcodeRotation.Clockwise_270;
            }
            switch (type)
            {
            case BarcodeType.GS1_128A:
                if (hasQuiteZones)
                {
                    widthShould = (GS1_128Data.QuietZoneMinimumWidth * 2 + BarcodesTestData.encodedTestDataGS1_128A.Length) * scaleMultiplier;
                }
                else
                {
                    widthShould = BarcodesTestData.encodedTestDataGS1_128A.Length * scaleMultiplier;
                }
                int heightShould = (int)(widthShould * 0.15f);
                heightShould = heightShould - (int)(heightShould * BarcodesUtils.GetPercentToCut(heightShould, heightToCut, scaleMultiplier) / 100);
                heightShould = heightShould + (int)labelHeight;
                Bitmap bitmap = BarcodesRenderer.DrawBitmapGS1_128(
                    BarcodesTestData.encodedTestDataGS1_128A,
                    BarcodesTestData.inputTestStringGS1_128A,
                    heightToCut,
                    true, scaleMultiplier, null, null, hasQuiteZones, rotation);
                if (rotate270)
                {
                    bitmap.Width.Should().Be(heightShould);
                    bitmap.Height.Should().Be(widthShould);
                }
                else
                {
                    bitmap.Width.Should().Be(widthShould);
                    bitmap.Height.Should().Be(heightShould);
                }
                break;

            case BarcodeType.GS1_128B:
                if (hasQuiteZones)
                {
                    widthShould = (GS1_128Data.QuietZoneMinimumWidth * 2 + BarcodesTestData.encodedTestDataGS1_128B.Length) * scaleMultiplier;
                }
                else
                {
                    widthShould = BarcodesTestData.encodedTestDataGS1_128B.Length * scaleMultiplier;
                }
                heightShould = (int)(widthShould * 0.15f);
                heightShould = heightShould - (int)(heightShould * BarcodesUtils.GetPercentToCut(heightShould, heightToCut, scaleMultiplier) / 100);
                heightShould = heightShould + (int)labelHeight;
                bitmap       = BarcodesRenderer.DrawBitmapGS1_128(
                    BarcodesTestData.encodedTestDataGS1_128B,
                    BarcodesTestData.inputTestStringGS1_128B,
                    heightToCut,
                    true, scaleMultiplier, null, null, hasQuiteZones, rotation);
                if (rotate270)
                {
                    bitmap.Width.Should().Be(heightShould);
                    bitmap.Height.Should().Be(widthShould);
                }
                else
                {
                    bitmap.Width.Should().Be(widthShould);
                    bitmap.Height.Should().Be(heightShould);
                }
                break;

            case BarcodeType.GS1_128C:
                if (hasQuiteZones)
                {
                    widthShould = (GS1_128Data.QuietZoneMinimumWidth * 2 + BarcodesTestData.encodedTestDataGS1_128C.Length) * scaleMultiplier;
                }
                else
                {
                    widthShould = BarcodesTestData.encodedTestDataGS1_128C.Length * scaleMultiplier;
                }
                heightShould = (int)(widthShould * 0.15f);
                heightShould = heightShould - (int)(heightShould * BarcodesUtils.GetPercentToCut(heightShould, heightToCut, scaleMultiplier) / 100);
                heightShould = heightShould + (int)labelHeight;
                bitmap       = BarcodesRenderer.DrawBitmapGS1_128(
                    BarcodesTestData.encodedTestDataGS1_128C,
                    BarcodesTestData.inputTestStringGS1_128C,
                    heightToCut,
                    true, scaleMultiplier, null, null, hasQuiteZones, rotation);
                if (rotate270)
                {
                    bitmap.Width.Should().Be(heightShould);
                    bitmap.Height.Should().Be(widthShould);
                }
                else
                {
                    bitmap.Width.Should().Be(widthShould);
                    bitmap.Height.Should().Be(heightShould);
                }
                break;
            }
            Assert.True(true, caseName);
        }
        public void Test_Renderer_EAN_UPC(BarcodeType type, MeasureBarcodeType heightToCutType, float heightToCutValue, int scaleMultiplier, bool hasQuiteZones, bool rotate90, string caseName)
        {
            MeasureBarcodeUnit heightToCut = new MeasureBarcodeUnit(heightToCutValue, heightToCutType);
            BarcodeRotation    rotation    = BarcodeRotation.Clockwise_0;

            if (rotate90)
            {
                rotation = BarcodeRotation.Clockwise_90;
            }
            switch (type)
            {
            case BarcodeType.EAN_13:
                int widthShould  = EANData.default_barcode_width_EAN_13 * scaleMultiplier;
                int heightShould = BarcodesUtils.GetBarcodeHeightInt(widthShould, type);
                heightShould = heightShould - (int)(heightShould * BarcodesUtils.GetPercentToCut(heightShould, heightToCut, scaleMultiplier) / 100);
                Bitmap bitmap = BarcodesRenderer.DrawBitmapEAN_UPC(
                    BarcodesTestData.encodedTestDataEAN_13,
                    BarcodesTestData.inputTestStringEAN_13,
                    type, heightToCut, true, scaleMultiplier, null, null, hasQuiteZones, rotation);
                if (!hasQuiteZones)
                {
                    widthShould = widthShould - (EANData.left_quite_zone_count_EAN_13 + EANData.right_quite_zone_count) * scaleMultiplier;
                }
                if (rotate90)
                {
                    bitmap.Width.Should().Be(heightShould);
                    bitmap.Height.Should().Be(widthShould);
                }
                else
                {
                    bitmap.Width.Should().Be(widthShould);
                    bitmap.Height.Should().Be(heightShould);
                }
                break;

            case BarcodeType.EAN_8:
                widthShould  = EANData.default_barcode_width_EAN_8 * scaleMultiplier;
                heightShould = BarcodesUtils.GetBarcodeHeightInt(widthShould, type);
                heightShould = heightShould - (int)(heightShould * BarcodesUtils.GetPercentToCut(heightShould, heightToCut, scaleMultiplier) / 100);
                bitmap       = BarcodesRenderer.DrawBitmapEAN_UPC(
                    BarcodesTestData.encodedTestDataEAN_8,
                    BarcodesTestData.inputTestStringEAN_8,
                    type, heightToCut, true, scaleMultiplier, null, null, hasQuiteZones, rotation);
                if (!hasQuiteZones)
                {
                    widthShould = widthShould - (EANData.left_quite_zone_count_EAN_8 + EANData.right_quite_zone_count) * scaleMultiplier;
                }
                if (rotate90)
                {
                    bitmap.Width.Should().Be(heightShould);
                    bitmap.Height.Should().Be(widthShould);
                }
                else
                {
                    bitmap.Width.Should().Be(widthShould);
                    bitmap.Height.Should().Be(heightShould);
                }
                break;

            case BarcodeType.UPC_A:
                widthShould  = EANData.default_barcode_width_EAN_13 * scaleMultiplier;
                heightShould = BarcodesUtils.GetBarcodeHeightInt(widthShould, type);
                heightShould = heightShould - (int)(heightShould * BarcodesUtils.GetPercentToCut(heightShould, heightToCut, scaleMultiplier) / 100);
                bitmap       = BarcodesRenderer.DrawBitmapEAN_UPC(
                    BarcodesTestData.encodedTestDataUPC_A,
                    BarcodesTestData.inputTestStringUPC_A,
                    type, heightToCut, true, scaleMultiplier, null, null, hasQuiteZones, rotation);
                if (!hasQuiteZones)
                {
                    widthShould = widthShould - (EANData.left_quite_zone_count_EAN_13 + EANData.right_quite_zone_count) * scaleMultiplier;
                }
                if (rotate90)
                {
                    bitmap.Width.Should().Be(heightShould);
                    bitmap.Height.Should().Be(widthShould);
                }
                else
                {
                    bitmap.Width.Should().Be(widthShould);
                    bitmap.Height.Should().Be(heightShould);
                }
                break;
            }

            Assert.True(true, caseName);
        }
예제 #13
0
        /// <summary>
        /// Draws a EAN/UPC barcode on bitmap from the encoded data depending on the barcode type and returns bitmap.
        /// </summary>
        /// <param name="encodedData">The encoded data.</param>
        /// <param name="barcodeType">The barcode type.</param>
        /// <param name="strokeColor">The color of barcode lines.</param>
        /// <param name="backColor">The background color.</param>
        /// <param name="showDataLabel">Defines whether to print the barcode data under the lines.</param>
        /// <param name="textDataString">The text to be printed under the barcode lines.</param>
        /// <param name="heightToCut">The height in pixels or in percent to be cut from the top of the barcode lines. Can be 0.</param>
        /// <param name="scaleMultiplier">The multiplier of the barcode width for better text rendering.</param>
        /// <param name="hasQuietZones">Defines whether the barcode has quiet zones.</param>
        /// <param name="barcodeRotation">Defines barcode rotation angle.</param>
        /// <returns>Bitmap</returns>
        internal static Bitmap DrawBitmapEAN_UPC(byte[] encodedData, string textDataString, BarcodeType barcodeType,
                                                 MeasureBarcodeUnit heightToCut, bool showDataLabel, int scaleMultiplier = 2, Color?strokeColor = null, Color?backColor = null,
                                                 bool hasQuietZones = true, BarcodeRotation barcodeRotation = BarcodeRotation.Clockwise_0)
        {
            // Bitmap accepts only integer values:
            int    barcodeWidth;
            int    barcodeHeight;
            int    strokeHeight;
            int    separatorHeight;
            int    leftQuiteZoneCount;
            int    leftCodePartCount;
            int    shiftFromTop   = EANData.shift_from_top * scaleMultiplier;
            Font   labelFont      = new Font(EANData.font_family_name, EANData.default_font_size * scaleMultiplier);
            Font   labelFontSmall = new Font(EANData.font_family_name, EANData.default_font_small_size * scaleMultiplier);
            string textDataLeft;
            string textDataRight;
            int    dotsPerInch      = EANData.dots_per_inch;
            int    halfBarItemWidth = scaleMultiplier / 2;

            switch (barcodeType)
            {
            case BarcodeType.EAN_13:
            case BarcodeType.UPC_A:
                barcodeWidth       = EANData.default_barcode_width_EAN_13 * scaleMultiplier;
                barcodeHeight      = BarcodesUtils.GetBarcodeHeightInt(EANData.default_barcode_width_EAN_13 * scaleMultiplier, barcodeType);
                strokeHeight       = BarcodesUtils.GetStrokeHeight(EANData.default_barcode_width_EAN_13 * scaleMultiplier, barcodeType);
                separatorHeight    = BarcodesUtils.GetSeparatorHeight(EANData.default_barcode_width_EAN_13 * scaleMultiplier, barcodeType);
                leftQuiteZoneCount = EANData.left_quite_zone_count_EAN_13;
                leftCodePartCount  = 42;
                textDataLeft       = textDataString.Substring(0, 6);
                textDataRight      = textDataString.Substring(6, 6);
                if (barcodeType == BarcodeType.UPC_A)
                {
                    textDataLeft  = textDataLeft.Substring(1, 5);
                    textDataRight = textDataRight.Substring(0, 5);
                }
                break;

            case BarcodeType.EAN_8:
                barcodeWidth       = EANData.default_barcode_width_EAN_8 * scaleMultiplier;
                barcodeHeight      = BarcodesUtils.GetBarcodeHeightInt(EANData.default_barcode_width_EAN_8 * scaleMultiplier, barcodeType);
                strokeHeight       = BarcodesUtils.GetStrokeHeight(EANData.default_barcode_width_EAN_8 * scaleMultiplier, barcodeType);
                separatorHeight    = BarcodesUtils.GetSeparatorHeight(EANData.default_barcode_width_EAN_8 * scaleMultiplier, barcodeType);
                leftQuiteZoneCount = EANData.left_quite_zone_count_EAN_8;
                leftCodePartCount  = 28;
                textDataLeft       = textDataString.Substring(0, 4);
                textDataRight      = textDataString.Substring(4, 4);
                break;

            default:
                throw new System.NotImplementedException("BarcodeType is not supported");
            }

            int leftSeparatorCount   = 3;
            int middleSeparatorCount = 5;
            int rightQuiteZoneCount  = EANData.right_quite_zone_count;

            if (!hasQuietZones)
            {
                barcodeWidth        = barcodeWidth - (leftQuiteZoneCount + rightQuiteZoneCount) * scaleMultiplier;
                leftQuiteZoneCount  = 0;
                rightQuiteZoneCount = 0;
            }

            // Calculate the percent the user wants to cut from the top depending on height:
            float percentToCut = BarcodesUtils.GetPercentToCut(barcodeHeight, heightToCut, scaleMultiplier);

            int cut = (int)(barcodeHeight * percentToCut / 100);

            strokeHeight    = Math.Max(strokeHeight - cut, 0);
            separatorHeight = Math.Max(separatorHeight - cut, 0);
            barcodeHeight   = barcodeHeight - cut;

            Bitmap bitmap;

            bitmap = new Bitmap(barcodeWidth, barcodeHeight);

            bitmap.SetResolution(dotsPerInch, dotsPerInch);

            using (var graphics = Graphics.FromImage(bitmap))
            {
                void DrawStrokeLine(int pos, bool isSeparator = false)
                {
                    graphics.DrawLine(new Pen(strokeColor ?? Color.Black, scaleMultiplier),
                                      new PointF(pos * scaleMultiplier + halfBarItemWidth, shiftFromTop),
                                      new PointF(pos * scaleMultiplier + halfBarItemWidth, shiftFromTop + (isSeparator ? separatorHeight : strokeHeight)));
                }

                void DrawSpaceLine(int pos, bool isSeparator = false)
                {
                    graphics.DrawLine(new Pen(backColor ?? Color.White, scaleMultiplier),
                                      new PointF(pos * scaleMultiplier + halfBarItemWidth, shiftFromTop),
                                      new PointF(pos * scaleMultiplier + halfBarItemWidth, shiftFromTop + (isSeparator ? separatorHeight : strokeHeight)));
                }

                // Paint the background:
                graphics.Clear(backColor ?? Color.White);

                int x = 0;

                // Left quite zone:
                while (x < leftQuiteZoneCount)
                {
                    DrawSpaceLine(x++);
                }

                // Left separator:
                DrawStrokeLine(x++, true);
                DrawSpaceLine(x++, true);
                DrawStrokeLine(x++, true);

                // Left part of the barcode:
                while (x - leftQuiteZoneCount - leftSeparatorCount < leftCodePartCount)
                {
                    // First digit of UPC must be longer than the others:
                    bool isFirstDigit = (x - leftQuiteZoneCount - leftSeparatorCount >= 0) && (x - leftQuiteZoneCount - leftSeparatorCount <= 6);
                    if (encodedData[x - leftQuiteZoneCount - leftSeparatorCount] == 1)
                    {
                        DrawStrokeLine(x, (barcodeType == BarcodeType.UPC_A) && isFirstDigit);
                    }
                    else
                    {
                        DrawSpaceLine(x, (barcodeType == BarcodeType.UPC_A) && isFirstDigit);
                    }
                    x++;
                }

                // Middle separator:
                DrawSpaceLine(x++, true);
                DrawStrokeLine(x++, true);
                DrawSpaceLine(x++, true);
                DrawStrokeLine(x++, true);
                DrawSpaceLine(x++, true);

                // Right part of the barcode:
                while (x - leftQuiteZoneCount - leftSeparatorCount - middleSeparatorCount < leftCodePartCount * 2)
                {
                    // Last digit of UPC must be longer than the others:
                    bool isLastDigit = (x - leftQuiteZoneCount - leftSeparatorCount - middleSeparatorCount >= 77) && (x - leftQuiteZoneCount - leftSeparatorCount - middleSeparatorCount <= 83);
                    if (encodedData[x - leftQuiteZoneCount - leftSeparatorCount - middleSeparatorCount] == 1)
                    {
                        DrawStrokeLine(x, (barcodeType == BarcodeType.UPC_A) && isLastDigit);
                    }
                    else
                    {
                        DrawSpaceLine(x, (barcodeType == BarcodeType.UPC_A) && isLastDigit);
                    }
                    x++;
                }

                // Right separator:
                DrawStrokeLine(x++, true);
                DrawSpaceLine(x++, true);
                DrawStrokeLine(x++, true);

                // Right quite zone:
                for (int i = 0; i < rightQuiteZoneCount; i++)
                {
                    DrawSpaceLine(x++);
                }

                if (showDataLabel)
                {
                    var digitsPath  = new GraphicsPath();
                    var digitsBrush = new SolidBrush(strokeColor ?? Color.Black);

                    int oneDigitShift = 0;
                    if (barcodeType == BarcodeType.UPC_A)
                    {
                        oneDigitShift = 7;
                    }

                    graphics.SmoothingMode = SmoothingMode.AntiAlias;

                    float textPosY = barcodeHeight - 1 - labelFont.Size;

                    digitsPath.AddString(textDataLeft, labelFont.FontFamily, (int)labelFont.Style, labelFont.Size,
                                         new RectangleF(
                                             (leftQuiteZoneCount + leftSeparatorCount + oneDigitShift + 3) * scaleMultiplier,
                                             textPosY,
                                             (leftCodePartCount + 7) * scaleMultiplier,
                                             labelFont.Height
                                             ),
                                         StringFormat.GenericTypographic);
                    digitsPath.AddString(textDataRight, labelFont.FontFamily, (int)labelFont.Style, labelFont.Size,
                                         new RectangleF(
                                             (leftQuiteZoneCount + leftSeparatorCount + 2 + leftCodePartCount + middleSeparatorCount) * scaleMultiplier,
                                             textPosY,
                                             (leftCodePartCount + 7) * scaleMultiplier,
                                             labelFont.Height
                                             ),
                                         StringFormat.GenericTypographic);

                    // Print the first digit for EAN-13:
                    if ((barcodeType == BarcodeType.EAN_13) && hasQuietZones)
                    {
                        digitsPath.AddString(textDataString.Substring(0, 1), labelFont.FontFamily, (int)labelFont.Style, labelFont.Size,
                                             new RectangleF(
                                                 1 * scaleMultiplier,
                                                 textPosY,
                                                 (leftCodePartCount + 7) * scaleMultiplier,
                                                 labelFont.Height
                                                 ),
                                             StringFormat.GenericTypographic);
                    }

                    // Print the first and the last digits for UPC-A:
                    if ((barcodeType == BarcodeType.UPC_A) && hasQuietZones)
                    {
                        digitsPath.AddString(textDataString.Substring(0, 1), labelFontSmall.FontFamily, (int)labelFontSmall.Style, labelFontSmall.Size,
                                             new RectangleF(
                                                 2 * scaleMultiplier,
                                                 (textPosY + labelFont.Size - labelFontSmall.Size),
                                                 (7) * scaleMultiplier,
                                                 labelFontSmall.Height
                                                 ),
                                             StringFormat.GenericTypographic);

                        digitsPath.AddString(textDataRight, labelFontSmall.FontFamily, (int)labelFontSmall.Style, labelFontSmall.Size,
                                             new RectangleF(
                                                 (leftQuiteZoneCount + leftSeparatorCount * 2 + 2 + leftCodePartCount * 2 + middleSeparatorCount) * scaleMultiplier,
                                                 (textPosY + labelFont.Size - labelFontSmall.Size),
                                                 (7) * scaleMultiplier,
                                                 labelFontSmall.Height
                                                 ),
                                             StringFormat.GenericTypographic);
                    }

                    graphics.FillPath(digitsBrush, digitsPath);
                }
            }

            switch (barcodeRotation)
            {
            case BarcodeRotation.Clockwise_90:
                bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
                break;

            case BarcodeRotation.Clockwise_180:
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                break;

            case BarcodeRotation.Clockwise_270:
                bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
                break;
            }

            return(bitmap);
        }
예제 #14
0
        /// <summary>
        /// Draws a GS1-128 barcode on bitmap from the encoded data and returns bitmap.
        /// </summary>
        /// <param name="encodedData">The encoded data.</param>
        /// <param name="textDataString">The text to be printed under the barcode lines.</param>
        /// <param name="heightToCut">The height in pixels or in percent to be cut from the top of the barcode lines. Can be 0.</param>
        /// <param name="showDataLabel">Defines whether to print the barcode data under the lines.</param>
        /// <param name="scaleMultiplier">The multiplier of the barcode width for better text rendering.</param>
        /// <param name="backColor">The background color.</param>
        /// <param name="hasQuietZones">Defines whether the barcode has quiet zones.</param>
        /// <param name="strokeColor">The color of barcode lines.</param>
        /// <param name="barcodeRotation">Defines barcode rotation angle.</param>
        /// <returns>Bitmap</returns>
        internal static Bitmap DrawBitmapGS1_128(byte[] encodedData, string textDataString,
                                                 MeasureBarcodeUnit heightToCut, bool showDataLabel = true, int scaleMultiplier = 2,
                                                 Color?strokeColor = null, Color?backColor = null, bool hasQuietZones = true,
                                                 BarcodeRotation barcodeRotation = BarcodeRotation.Clockwise_0)
        {
            int halfBarItemWidth = scaleMultiplier / 2;

            int quietZoneWidth = GS1_128Data.QuietZoneMinimumWidth * scaleMultiplier;

            if (!hasQuietZones)
            {
                quietZoneWidth = 0;
            }

            int internalWidth = quietZoneWidth * 2 + encodedData.Length * scaleMultiplier;

            // Barcode height is 15% of the width:
            int internalHeight = (int)(internalWidth * 0.15f);

            // Calculate the percent depending on height:
            float percentToCut = BarcodesUtils.GetPercentToCut(internalHeight, heightToCut, scaleMultiplier);

            internalHeight = internalHeight - (int)(internalHeight * percentToCut / 100);

            Font labelFont = new Font(GS1_128Data.font_family_name, GS1_128Data.default_font_size * scaleMultiplier);

            float labelY = 0f, labelHeight = 0f;
            float labelWidth = 0f;

            if (showDataLabel)
            {
                labelHeight  = scaleMultiplier * 2;
                labelY       = labelHeight + internalHeight;
                labelHeight += labelFont.Size;
                using (var temp = new Bitmap(1, 1))
                    using (var g = Graphics.FromImage(temp))
                        labelWidth = g.MeasureString(textDataString, labelFont).Width;
            }

            var bitmap = new Bitmap(internalWidth, internalHeight + (int)labelHeight);

            int dotsPerInch = GS1_128Data.dots_per_inch;

            bitmap.SetResolution(dotsPerInch, dotsPerInch);

            int pos = 0;

            using (var graphics = Graphics.FromImage(bitmap))
            {
                graphics.Clear(backColor ?? Color.White);

                Pen   backgroundPen   = new Pen(backColor ?? Color.White, scaleMultiplier);
                Pen   strokePen       = new Pen(strokeColor ?? Color.Black, scaleMultiplier);
                Brush backgroundBrush = new SolidBrush(backColor ?? Color.White);

                // 1. Left quiet zone
                graphics.FillRectangle(backgroundBrush,
                                       x: 0, y: 0,
                                       width: quietZoneWidth, height: internalHeight);
                pos += quietZoneWidth; // quiet zone is 10 * X here

                // 2. Stop character
                for (int i = 0; i < encodedData.Length; i++)
                {
                    graphics.DrawLine(encodedData[i] == 1 ? strokePen : backgroundPen,
                                      new Point(pos + halfBarItemWidth, 0),
                                      new Point(pos + halfBarItemWidth, internalHeight));

                    pos += scaleMultiplier;
                }

                // 3. Right quiet zone
                graphics.FillRectangle(backgroundBrush,
                                       x: pos + halfBarItemWidth, y: 0,
                                       width: quietZoneWidth, height: internalHeight);

                // 4. Print data string under the barcode
                if (showDataLabel)
                {
                    labelY = internalHeight + 1;

                    graphics.SmoothingMode = SmoothingMode.AntiAlias;

                    var labelPath  = new GraphicsPath();
                    var labelBrush = new SolidBrush(strokeColor ?? Color.Black);

                    labelPath.AddString(textDataString, labelFont.FontFamily, (int)labelFont.Style, labelFont.Size,
                                        new RectangleF(x: internalWidth / 2f - labelWidth / 2, y: labelY, labelWidth, labelHeight),
                                        new StringFormat(StringFormat.GenericTypographic)
                    {
                        Alignment = StringAlignment.Center
                    });

                    graphics.FillPath(labelBrush, labelPath);
                }
            }

            switch (barcodeRotation)
            {
            case BarcodeRotation.Clockwise_90:
                bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
                break;

            case BarcodeRotation.Clockwise_180:
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                break;

            case BarcodeRotation.Clockwise_270:
                bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
                break;
            }

            return(bitmap);
        }