Generate Cobined Barcode (1D + 2D)

Hi guys

I’m currently working on a project that requires generating both 1D and 2D symbologies simultaneously in the same SVG file.

Example:

image.png (18,0 KB)

image.png (18,4 KB)

Is this possible with Aspose technology?

I’m asking this because before purchasing any license, I’d like to be sure I’m making the right purchase.

Thank you very much.
image.png (18.0 KB)
image.png (18.4 KB)

1 Like

@fgonzalez,

You can use Aspose.BarCode that allows you to create multiple barcodes of different types within single image, including postal, QR Code, PDF417, EAN, Code 39, Code 128, ISBN, MSI, and others. See the document with example code on how to Generate Multiple Barcodes within Single Image|Documentation for your reference.

Thank you @fgonzalez

I’m sorry for fast replay from @amjad.sahi about code example for Bitmap images.

Here is updated response in case of SVG images.

At the moment, Aspose.BarCode (Cloud and on-prem) renders one barcode per request. We don’t offer a dedicated “composite SVG” endpoint that automatically lays out multiple symbologies, but you can compose them yourself - for example, EAN-13 and QR on the same canvas. It’s straightforward: generate each barcode as SVG (these requests can run in parallel), then combine them on your side.

Tell me which language you’re using, and I’ll provide a code example.

For example C# code:

private static string CombineSvg(string eanSvg, string qrSvg)
	{
		XDocument eanDoc = XDocument.Parse(eanSvg);
		XDocument qrDoc = XDocument.Parse(qrSvg);

		double eanWidth = ParseLength(eanDoc.Root?.Attribute("width"));
		double eanHeight = ParseLength(eanDoc.Root?.Attribute("height"));
		double qrWidth = ParseLength(qrDoc.Root?.Attribute("width"));
		double qrHeight = ParseLength(qrDoc.Root?.Attribute("height"));

		double combinedWidth = eanWidth + BarcodeSpacing + qrWidth;
		double combinedHeight = Math.Max(eanHeight, qrHeight);

		XNamespace svgNamespace = eanDoc.Root?.Name.Namespace ?? "http://www.w3.org/2000/svg";
		var combinedRoot = new XElement(svgNamespace + "svg",
			new XAttribute("xmlns", svgNamespace.NamespaceName),
			new XAttribute(XNamespace.Xmlns + "xlink", "http://www.w3.org/1999/xlink"),
			new XAttribute("width", ToInvariantLength(combinedWidth)),
			new XAttribute("height", ToInvariantLength(combinedHeight)),
			new XAttribute("viewBox", $"0 0 {ToInvariantLength(combinedWidth)} {ToInvariantLength(combinedHeight)}"));

		double eanOffsetY = Math.Max(0, (combinedHeight - eanHeight) / 2);
		double qrOffsetY = Math.Max(0, (combinedHeight - qrHeight) / 2);

		combinedRoot.Add(CreateNestedSvg(eanDoc, 0, eanOffsetY, "EAN13"));
		combinedRoot.Add(CreateNestedSvg(qrDoc, eanWidth + BarcodeSpacing, qrOffsetY, "QR"));

		return combinedRoot.ToString(SaveOptions.OmitDuplicateNamespaces);
	}

	private static XElement CreateNestedSvg(XDocument source, double offsetX, double offsetY, string label)
	{
		if (source.Root == null)
		{
			throw new InvalidOperationException("SVG document does not have a root element.");
		}

		var nested = new XElement(source.Root);
		nested.SetAttributeValue("x", ToInvariantLength(offsetX));
		nested.SetAttributeValue("y", ToInvariantLength(offsetY));
		nested.SetAttributeValue("data-barcode", label);
		return nested;
	}

	private static double ParseLength(XAttribute? attribute, double fallback = 100d)
	{
		if (string.IsNullOrWhiteSpace(attribute?.Value))
		{
			return fallback;
		}

		var buffer = new StringBuilder();
		foreach (char c in attribute.Value)
		{
			if (char.IsDigit(c) || c == '.' || c == '-')
			{
				buffer.Append(c);
			}
			else if (buffer.Length > 0)
			{
				break;
			}
		}

		return double.TryParse(buffer.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out double parsed)
			? parsed
			: fallback;
	}

	private static string ToInvariantLength(double value)
	{
		return value.ToString("0.##", CultureInfo.InvariantCulture);
	}