Using Barcodes with Word merge produces black blobs

Hi, can you please point me in the direction of an example that using barcodes in a Word merge? I would have throught this was basic functionality. None of the examples on your site (that I have found so far) work. They either crash with an error saying “barcode is too small” or if you mess with the scaling they don’t crash but just output a black blob.

The MERGEBARCODE field appear to be working as they render the correct DISPLAYBARCODE fields in Word if you save as a docx and open Word renders them as expected so the problem seems to be in the save as PDF function where the custom image handler needs to generate the barcode.

Regards
Adam

This is the example in your docs which I tried.

Document doc = new Document();
                DocumentBuilder builder = new DocumentBuilder(doc);

                doc.FieldOptions.BarcodeGenerator = new CustomBarcodeGenerator();


                // Insert a QR code
                FieldMergeBarcode field = (FieldMergeBarcode)builder.InsertField(FieldType.FieldMergeBarcode, true);
                field.BarcodeType = "QR";

                // In a DISPLAYBARCODE field, the BarcodeValue attribute decides what value the barcode will display
                // However in our MERGEBARCODE fields, it has the same function as the FieldName attribute of a MERGEFIELD
                field.BarcodeValue = "MyQRCode";
                field.BackgroundColor = "0xF8BD69";
                field.ForegroundColor = "0xB5413B";
                field.ErrorCorrectionLevel = "3";
                field.ScalingFactor = "500";
                field.SymbolHeight = "2000";
                field.SymbolRotation = "0";

                string value = field.GetFieldCode();
                //                Assert.AreEqual(" MERGEBARCODE  MyQRCode QR \\b 0xF8BD69 \\f 0xB5413B \\q 3 \\s 250 \\h 1000 \\r 0",
                //field.GetFieldCode());
                //builder.Writeln();

                // Create a data source for our mail merge
                // This source is a data table, whose column names correspond to the FieldName attributes of MERGEFIELD fields
                // as well as BarcodeValue attributes of DISPLAYBARCODE fields
                DataTable table = new DataTable();
                table.Columns.Add("MyQRCode");
                table.Rows.Add(new object[] {
                    "ABC123",
                });
                table.Rows.Add(new object[] {
                    "DEF456",
                });

                // During the mail merge, all our MERGEBARCODE fields will be converted into DISPLAYBARCODE fields,
                // with values from the data table rows deposited into corresponding BarcodeValue attributes
                doc.MailMerge.Execute(table);

                var fieldType = doc.Range.Fields[0].Type;
                var fieldType2 = doc.Range.Fields[1].Type;

                string fieldCode = doc.Range.Fields[0].GetFieldCode();
                string fieldCode2 = doc.Range.Fields[1].GetFieldCode();

                //Assert.AreEqual("DISPLAYBARCODE \"ABC123\" QR \\q 3 \\s 250 \\h 1000 \\r 0 \\b 0xF8BD69 \\f 0xB5413B",
                //);
                //Assert.AreEqual("DISPLAYBARCODE \"DEF456\" QR \\q 3 \\s 250 \\h 1000 \\r 0 \\b 0xF8BD69 \\f 0xB5413B",
                //;

                //                var saveOptions = Aspose.Words.Saving.SaveOptions.CreateSaveOptions(Aspose.Words.SaveFormat.Pdf);

                doc.Save("c:\\temp\\fubar.pdf", SaveFormat.Pdf);

  public class CustomBarcodeGenerator : IBarcodeGenerator
    {
        /// <summary>
        /// Converts barcode image height from Word units to Aspose.BarCode units.
        /// </summary>
        /// <param name="heightInTwipsString"></param>
        /// <returns></returns>
        private static float ConvertSymbolHeight(string heightInTwipsString)
        {
            // Input value is in 1/1440 inches (twips)
            int heightInTwips = int.MinValue;
            int.TryParse(heightInTwipsString, out heightInTwips);

            if (heightInTwips == int.MinValue)
                throw new Exception("Error! Incorrect height - " + heightInTwipsString + ".");

            // Convert to mm
            return (float)(heightInTwips * 25.4 / 1440);
        }

        /// <summary>
        /// Converts barcode image color from Word to Aspose.BarCode.
        /// </summary>
        /// <param name="inputColor"></param>
        /// <returns></returns>
        private static Color ConvertColor(string inputColor)
        {
            // Input should be from "0x000000" to "0xFFFFFF"
            int color = int.MinValue;
            int.TryParse(inputColor.Replace("0x", ""), out color);

            if (color == int.MinValue)
                throw new Exception("Error! Incorrect color - " + inputColor + ".");

            return Color.FromArgb(color >> 16, (color & 0xFF00) >> 8, color & 0xFF);

            // Backword conversion -
            //return string.Format("0x{0,6:X6}", mControl.ForeColor.ToArgb() & 0xFFFFFF);
        }

        /// <summary>
        /// Converts bar code scaling factor from percents to float.
        /// </summary>
        /// <param name="scalingFactor"></param>
        /// <returns></returns>
        private static float ConvertScalingFactor(string scalingFactor)
        {
            bool isParsed = false;
            int percents = int.MinValue;
            int.TryParse(scalingFactor, out percents);

            if (percents != int.MinValue)
            {
                if (percents >= 10 && percents <= 10000)
                    isParsed = true;
            }

            if (!isParsed)
                throw new Exception("Error! Incorrect scaling factor - " + scalingFactor + ".");

            return percents / 100.0f;
        }

        /// <summary>
        /// Implementation of the GetBarCodeImage() method for IBarCodeGenerator interface.
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public Image GetBarcodeImage(Aspose.Words.Fields.BarcodeParameters parameters)
        {
            if (parameters.BarcodeType == null || parameters.BarcodeValue == null)
                return null;

            string type = parameters.BarcodeType.ToUpper();
            var encodeType = EncodeTypes.None;

            switch (type)
            {
                case "QR":
                    encodeType = EncodeTypes.QR;
                    break;
                case "CODE128":
                    encodeType = EncodeTypes.Code128;
                    break;
                case "CODE39":
                    encodeType = EncodeTypes.Code39Standard;
                    break;
                case "EAN8":
                    encodeType = EncodeTypes.EAN8;
                    break;
                case "EAN13":
                    encodeType = EncodeTypes.EAN13;
                    break;
                case "UPCA":
                    encodeType = EncodeTypes.UPCA;
                    break;
                case "UPCE":
                    encodeType = EncodeTypes.UPCE;
                    break;
                case "ITF14":
                    encodeType = EncodeTypes.ITF14;
                    break;
                case "CASE":
                    encodeType = EncodeTypes.None;
                    break;
            }

            if (encodeType == EncodeTypes.None)
                return null;

            BarcodeGenerator generator = new BarcodeGenerator(encodeType);
            generator.CodeText = parameters.BarcodeValue;

            if (encodeType == EncodeTypes.QR)
                generator.Parameters.Barcode.CodeTextParameters.TwoDDisplayText = parameters.BarcodeValue;

            if (parameters.ForegroundColor != null)
                generator.Parameters.Barcode.ForeColor = ConvertColor(parameters.ForegroundColor);

            if (parameters.BackgroundColor != null)
                generator.Parameters.BackColor = ConvertColor(parameters.BackgroundColor);

            if (parameters.SymbolHeight != null)
            {
                generator.Parameters.Barcode.BarCodeHeight.Millimeters = ConvertSymbolHeight(parameters.SymbolHeight);
                generator.Parameters.Barcode.AutoSizeMode = AutoSizeMode.Nearest;
            }

            generator.Parameters.Barcode.CodeTextParameters.Location = CodeLocation.None;

            if (parameters.DisplayText)
                generator.Parameters.Barcode.CodeTextParameters.Location = CodeLocation.Below;

            generator.Parameters.CaptionAbove.Text = "";

            const float scale = 1.0f; // Empiric scaling factor for converting Word barcode to Aspose.BarCode
            float xdim = 1.0f;

            if (encodeType == EncodeTypes.QR)
            {
                generator.Parameters.Barcode.AutoSizeMode = AutoSizeMode.Nearest;
                generator.Parameters.Barcode.BarCodeWidth.Millimeters *= scale;
                generator.Parameters.Barcode.BarCodeHeight.Millimeters = generator.Parameters.Barcode.BarCodeWidth.Millimeters;
                xdim = generator.Parameters.Barcode.BarCodeHeight.Millimeters / 25;
                generator.Parameters.Barcode.XDimension.Millimeters = generator.Parameters.Barcode.BarHeight.Millimeters = xdim;
            }

            if (parameters.ScalingFactor != null)
            {
                float scalingFactor = ConvertScalingFactor(parameters.ScalingFactor);
                generator.Parameters.Barcode.BarCodeHeight.Millimeters *= scalingFactor;
                if (encodeType == EncodeTypes.QR)
                {
                    generator.Parameters.Barcode.BarCodeWidth.Millimeters = generator.Parameters.Barcode.BarCodeHeight.Millimeters;
                    generator.Parameters.Barcode.XDimension.Millimeters = generator.Parameters.Barcode.BarHeight.Millimeters = xdim * scalingFactor;
                }

                generator.Parameters.Barcode.AutoSizeMode = AutoSizeMode.Nearest;
            }
            return generator.GenerateBarCodeImage();
        }

        public Image GetOldBarcodeImage(Aspose.Words.Fields.BarcodeParameters parameters)
        {
            throw new NotImplementedException();
        }
    }
1 Like

OK, after wasting a whole day on this I tried commenting out the background/foreground colour settings and it now works. Further debugging found the problem in your ConvertColor method always returns 0, black for any hex string because it is not a valid integer string. I fixed it as below and now it works for any colour string.

    private static Color ConvertColor(string inputColor)
    {
        int color = 0;
        try
        {
            color = Convert.ToInt32(inputColor, 16);
        }
        catch
        {
            throw new Exception("Error! Incorrect color - " + inputColor + ".");
        }

        return Color.FromArgb(color >> 16, (color & 0xFF00) >> 8, color & 0xFF);
    }

Please update your examples so that others do not waste their time.

Regards
Adam

@cibisinternational,

Thanks for providing us details and sample code segments.

Good to know that you have already sorted out your issue now. Generally the examples in the Docs are up-to-date and in accordance with latest APIs set. Anyways, we would love to update any example and document/article to make it up-to-date (if it is not already there). Could you point us which example(s)/document(s) you are referring to and are not up-to-date , we will check and fix the issue soon.