Code Snippets
Because the Zen Barcode documentation is non-existend I decided that a full working demo would be useful.
The snippet was made for .Net MVC, hence the [Display(Name = "Barcode type")]
attributes, but it can be used for any C# project.
First, a custom class to hold some extra barcode properties and the Enum types for the allowed content and error types.
public class Barcode { public BarcodeSymbology type { get; set; } public string description { get; set; } public int minTextLength { get; set; } public int maxTextLength { get; set; } public ContentType allowedContentType { get; set; } }
public enum ContentType { Numeric, AlphaNumeric, All }
public enum ContentError { None, NoData, NoBarcodeType, InputTooShort, InputTooLong, NotNumeric, NotAlphaNumeric }
Then the actual class to create the barcode based on the supplied variables.
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Text.RegularExpressions; using Zen.Barcode; public class BarcodeData { private int _height { get; set; } private int _width { get; set; } private int _padding { get; set; } [Required] [Display(Name = "Barcode type")] public BarcodeSymbology type { get; set; } [Required] [StringLength(512)] [Display(Name = "Barcode value")] public string value { get; set; } [Required] [Range(50, 1000)] [Display(Name = "Width")] public int width { get { if (_width < 50) return 50; else if (_width > 1000) return 1000; else return _width; } set { _width = value; } } [Required] [Range(30, 600)] [Display(Name = "Height")] public int height { get { if (_height < 30) return 30; else if (_height > 600) return 600; else return _height; } set { _height = value; } } [Required] [Range(0, 250)] [Display(Name = "Padding")] public int padding { get { if (_padding < 0) return 0; else if (_padding > 250) return 250; else return _padding; } set { _padding = value; } } [Display(Name = "Foreground color")] public string foregroundColor { get; set; } [Display(Name = "Background color")] public string backgroundColor { get; set; } [Display(Name = "Force width/height ratio")] public bool forceRatio { get; set; } public BarcodeData() { padding = 10; } public BarcodeData(BarcodeSymbology barcode_type, string barcode_value) { type = barcode_type; value = barcode_value; padding = 10; } //get all barcode types and define some properties like min and max length public List<Barcode> AllBarcodes() { return new List<Barcode>() { new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "11 C", type = BarcodeSymbology.Code11C }, new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "11 NC", type = BarcodeSymbology.Code11NC }, new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "25 Interleaved C", type = BarcodeSymbology.Code25InterleavedC }, new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "25 Interleaved NC", type = BarcodeSymbology.Code25InterleavedNC }, new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "25 Standard C", type = BarcodeSymbology.Code25StandardC }, new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "25 Standard NC", type = BarcodeSymbology.Code25StandardNC }, new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "39 C", type = BarcodeSymbology.Code39C }, new Barcode() { minTextLength = 3, maxTextLength = 64, allowedContentType = ContentType.AlphaNumeric, description = "39 NC", type = BarcodeSymbology.Code39NC }, new Barcode() { minTextLength = 3, maxTextLength = 32, allowedContentType = ContentType.Numeric, description = "93", type = BarcodeSymbology.Code93 }, new Barcode() { minTextLength = 3, maxTextLength = 64, allowedContentType = ContentType.AlphaNumeric, description = "128", type = BarcodeSymbology.Code128 }, new Barcode() { minTextLength = 7, maxTextLength = 7, allowedContentType = ContentType.Numeric, description = "EAN 8", type = BarcodeSymbology.CodeEan8 }, new Barcode() { minTextLength = 12, maxTextLength = 12, allowedContentType =Enums. ContentType.Numeric, description = "EAN 13", type = BarcodeSymbology.CodeEan13 }, new Barcode() { minTextLength = 3, maxTextLength = 512, allowedContentType = ContentType.All, description = "QR Code", type = BarcodeSymbology.CodeQr } }; } //validate the input. some barcodes are numeric only, some alphanumeric etc public Enums.ContentError Validate() { var regex = new Regex("^[a-zA-Z0-9-]*$"); var barcode = AllBarcodes().Where(x => x.type == type).FirstOrDefault(); if (barcode == null || barcode.type == BarcodeSymbology.Unknown) return ContentError.NoBarcodeType; else if (string.IsNullOrEmpty(value)) return ContentError.NoData; if (value.Length < barcode.minTextLength) return ContentError.InputTooShort; else if (value.Length > barcode.maxTextLength) return ContentError.InputTooLong; else if (barcode.allowedContentType == ContentType.Numeric && !value.All(char.IsDigit)) return ContentError.NotNumeric; else if (barcode.allowedContentType == ContentType.AlphaNumeric && !regex.IsMatch(value)) return ContentError.NotAlphaNumeric; else return ContentError.None; } //generate the barcode public byte[] Generate() { BarcodeDraw barcodeDraw = BarcodeDrawFactory.GetSymbology(type); BarcodeMetrics barcodeMetrics = barcodeDraw.GetDefaultMetrics(height); //calculate the scale double schaal = Math.Ceiling((double)width / 100); if (schaal < 1) { schaal = 1; } //when qr code double the scale if (type == BarcodeSymbology.CodeQr) { schaal = schaal * 2; } //set the scale to the barcode barcodeMetrics.Scale = (int)schaal; //generate the barcode var image = barcodeDraw.Draw(value, barcodeMetrics); //make a bitmap from the image and make it transparent by default var barcodeImage = new Bitmap(image); barcodeImage.MakeTransparent(Color.White); Bitmap paddedImage = null; Bitmap filledImage = null; Bitmap coloredImage = null; //add the padding if (padding > 0) { paddedImage = new Bitmap(barcodeImage.Width + (padding * 2), barcodeImage.Height + (padding * 2)); using (var gfx = Graphics.FromImage(paddedImage)) { //also add the background color while were at it if (!string.IsNullOrEmpty(backgroundColor)) { gfx.Clear(ColorTranslator.FromHtml(backgroundColor)); } //calculate the offset for the barcode image int x = (paddedImage.Width - barcodeImage.Width) / 2; int y = (paddedImage.Height - barcodeImage.Height) / 2; gfx.DrawImage(barcodeImage, x, y); } barcodeImage = paddedImage; } else if (!string.IsNullOrEmpty(backgroundColor)) //add the background color { filledImage = new Bitmap(barcodeImage.Width, barcodeImage.Height); using (var gfx = Graphics.FromImage(filledImage)) { gfx.Clear(ColorTranslator.FromHtml(backgroundColor)); gfx.DrawImage(barcodeImage, 0, 0); } barcodeImage = filledImage; } //replace the color of the barcode foreground with a new color. must be with this type of code //since the library does not seem to be able to specify a color for the barcode if (!string.IsNullOrEmpty(backgroundColor)) { coloredImage = new Bitmap(barcodeImage.Width, barcodeImage.Height); using (var gfx = Graphics.FromImage(coloredImage)) { //make a color map var colorMap = new ColorMap[1]; colorMap[0] = new ColorMap() { OldColor = Color.Black, NewColor = ColorTranslator.FromHtml(foregroundColor) }; //set the attributes var attr = new ImageAttributes(); attr.SetRemapTable(colorMap); //replace the color Rectangle rect = new Rectangle(0, 0, barcodeImage.Width, barcodeImage.Height); gfx.DrawImage(barcodeImage, rect, 0, 0, rect.Width, rect.Height, GraphicsUnit.Pixel, attr); barcodeImage = coloredImage; } } //force ratio bij resizing the image except qr codes if (forceRatio && type != BarcodeSymbology.CodeQr) { barcodeImage = Resize(barcodeImage, width, height); } //return the barcode as a bye array using (var stream = new MemoryStream()) { barcodeImage.Save(stream, ImageFormat.Png); //cleanup if (paddedImage != null) { paddedImage.Dispose(); } if (filledImage != null) { filledImage.Dispose(); } if (coloredImage != null) { coloredImage.Dispose(); } barcodeImage.Dispose(); //return the barcode return stream.ToArray(); } } }
And finally the Resize()
method that resizes the barcode when the dimensions are forced.
private static Bitmap Resize(Bitmap image, int width, int height) { var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); using (image) using (Graphics gfx = Graphics.FromImage(bmp)) { gfx.CompositingMode = CompositingMode.SourceCopy; gfx.CompositingQuality = CompositingQuality.HighQuality; gfx.SmoothingMode = SmoothingMode.HighQuality; gfx.InterpolationMode = InterpolationMode.HighQualityBicubic; gfx.PixelOffsetMode = PixelOffsetMode.HighQuality; gfx.DrawImage(image, new Rectangle(0, 0, width, height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel); } return bmp; }