using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; //using Curtain.Helpers; using ZXing; using ZXing.Common; using ZXing.OneD; using ZXing.Rendering; namespace Dongke.WinForm.Controls.InvoiceLayout.DrawBarcode.OneD { /// /// 一维码生成 /// public sealed class OneDHelper { private static readonly Dictionary formatWriter; private static readonly Dictionary formatMap; static OneDHelper() { formatWriter = new Dictionary() { { OneDFormat.CODE_128, new Code128Writer() }, { OneDFormat.EAN_13, new EAN13Writer() }, { OneDFormat.EAN_8, new EAN8Writer() }, { OneDFormat.CODABAR, new CodaBarWriter() }, { OneDFormat.CODE_39, new Code39Writer() }, { OneDFormat.CODE_93, new Code93Writer() }, { OneDFormat.ITF, new ITFWriter() }, { OneDFormat.MSI, new MSIWriter() }, { OneDFormat.PLESSEY, new PlesseyWriter() }, { OneDFormat.UPC_A, new UPCAWriter() }, { OneDFormat.UPC_E, new UPCEWriter() }, //formatMap.Add(OneDFormat.CODABAR, new CodaBarWriter()); //formatMap.Add(OneDFormat.CODE_39, new Code39Writer()); //formatMap.Add(OneDFormat.CODE_93, new Code93Writer()); //formatMap.Add(OneDFormat.EAN_8, new EAN8Writer()); //formatMap.Add(OneDFormat.ITF, new ITFWriter()); //formatMap.Add(OneDFormat.MSI, new MSIWriter()); //formatMap.Add(OneDFormat.PLESSEY, new PlesseyWriter()); //formatMap.Add(OneDFormat.UPC_A, new UPCAWriter()); //formatMap.Add(OneDFormat.UPC_E, new UPCEWriter()); // 二维 //formatMap.Add(BarcodeFormat.QR_CODE, new QRCodeWriter()); //formatMap.Add(BarcodeFormat.PDF_417, new PDF417Writer()); //formatMap.Add(BarcodeFormat.DATA_MATRIX, new DataMatrixWriter()); //formatMap.Add(BarcodeFormat.AZTEC, new AztecWriter()); }; formatMap = new Dictionary { { OneDFormat.CODE_128, BarcodeFormat.CODE_128 }, { OneDFormat.EAN_13, BarcodeFormat.EAN_13 }, { OneDFormat.EAN_8, BarcodeFormat.EAN_8 }, { OneDFormat.CODABAR, BarcodeFormat.CODABAR }, { OneDFormat.CODE_39, BarcodeFormat.CODE_39 }, { OneDFormat.CODE_93, BarcodeFormat.CODE_93 }, { OneDFormat.ITF, BarcodeFormat.ITF }, { OneDFormat.MSI, BarcodeFormat.MSI }, { OneDFormat.PLESSEY, BarcodeFormat.PLESSEY }, { OneDFormat.UPC_A, BarcodeFormat.UPC_A }, { OneDFormat.UPC_E, BarcodeFormat.UPC_E }, }; } /// /// 原始一维码 /// /// /// /// public static OneDData Encode(string contents, OneDFormat format = OneDFormat.CODE_128) { //OneDimensionalCodeWriter writer = null; Writer writer = null; if (formatWriter.ContainsKey(format)) { writer = formatWriter[format]; } if (writer == null) { return null; } OneDimensionalCodeWriter codeWriter; if (format == OneDFormat.UPC_A) { codeWriter = new EAN13Writer(); contents = "0" + contents; } else { codeWriter = writer as OneDimensionalCodeWriter; } bool[] code = codeWriter?.encode(contents); if (code == null || code.Length == 0) { return null; } OneDData data = new OneDData(code, contents); return data; } /// /// 按比例放大的原始一维码 /// /// /// /// /// public static OneDData Encode(string contents, int width, OneDFormat format = OneDFormat.CODE_128) { OneDData data = Encode(contents, format); if (data == null) { return null; } return Encode(data, width); } /// /// 按比例放大的原始一维码 /// /// /// /// public static OneDData Encode(OneDData data, int width) { if (data == null) { return null; } data.Width = width; //data.Height = height; //if (width < data.Size) //{ // throw new ArgumentOutOfRangeException("barcode width", width, $"data size is {data.Size}"); //} if (width <= data.Size) { return data; } int multiple = (width / data.Size); if (multiple == 1) { return data; } int dataSize = data.Size * multiple; OneDData oneData = new OneDData(dataSize) { Text = data.Text, Width = width, }; for (int x = 0; x < data.Size; x++) { int h = x * multiple; for (int i = h; i < h + multiple; i++) { oneData[i] = data[x]; } } return oneData; } /// /// 直接绘制条码 /// /// /// /// public static void DrawOneD(string contents, OneDDrawingOptions options, OneDFormat format = OneDFormat.CODE_128) { if (options?.DrawGraphics == null) { throw new ArgumentNullException("OneDDrawingOptions.DrawGraphics"); } if (options.ShowText) { /*Writer writer = null; if (formatWriter.ContainsKey(format)) { writer = formatWriter[format]; } if (writer == null) { return; } BarcodeFormat barcodeFormat = formatMap[format]; EncodingOptions encodingOptions = new EncodingOptions(); encodingOptions.Width = options.ImageWidth - options.Margin.Horizontal; encodingOptions.Height = options.ImageHeight - options.Margin.Vertical; if (options.TextMargin.HasValue) { encodingOptions.Hints.Add(EncodeHintType.MARGIN, options.TextMargin); } AlternateBitmapRenderer render = new AlternateBitmapRenderer(); if (options.TextFont != null) { render.TextFont = options.TextFont; if (format == OneDFormat.EAN_8 || format == OneDFormat.EAN_13 || format == OneDFormat.UPC_E || format == OneDFormat.UPC_A) { if (options.DpiX.HasValue) { // zxing AlternateBitmapRenderer 创建图片没有设置分辨率 render.TextFont = new Font(options.TextFont.FontFamily, options.TextFont.Size * options.DpiX.Value / 96, options.TextFont.Style); } } } try { BitMatrix m = writer.encode(contents, barcodeFormat, encodingOptions.Width, encodingOptions.Height, encodingOptions.Hints); using (Image image = render.Render(m, barcodeFormat, contents, encodingOptions)) { Rectangle rect = new Rectangle( options.ImageRect.Left + options.Margin.Left, options.ImageRect.Top + options.Margin.Top, //imageData.Width, //imageData.Height); options.ImageRect.Width - options.Margin.Horizontal, options.ImageRect.Height - options.Margin.Vertical); if (options.ShowType == BarcodeShowType.Zoom) { options.DrawGraphics.DrawImage(image, rect); } else if (options.ShowType == BarcodeShowType.Show) { ImageHelper.Show(image, options.DrawGraphics, rect, ContentAlignment.MiddleCenter, false); } else { ImageHelper.Show(image, options.DrawGraphics, rect, ContentAlignment.TopLeft, false); } } } catch (Exception ex) { Font errorFont = new Font("Courier New", 9f, FontStyle.Regular); options.DrawGraphics.DrawString(ex.Message, errorFont, Brushes.Red, options.ImageRect); }*/ using (Image image = GetOneDImage(contents, options, format)) { Rectangle rect = new Rectangle( options.ImageRect.Left + options.Margin.Left, options.ImageRect.Top + options.Margin.Top, //imageData.Width, //imageData.Height); options.ImageRect.Width - options.Margin.Horizontal, options.ImageRect.Height - options.Margin.Vertical); if (options.ShowType == BarcodeShowType.Zoom) { options.DrawGraphics.DrawImage(image, rect); } else if (options.ShowType == BarcodeShowType.Show) { ImageHelper.Show(image, options.DrawGraphics, rect, ContentAlignment.MiddleCenter, false); } else { ImageHelper.Show(image, options.DrawGraphics, rect, ContentAlignment.TopLeft, false); } } return; } OneDData data = Encode(contents, format); if (data == null) { return; } // 条码范围 int width = options.ImageRect.Width - options.Margin.Horizontal; int height = options.ImageRect.Height - options.Margin.Vertical; data = Encode(data, width); data.Height = height; DrawOneD(data, options.DrawGraphics, options); } /// /// 直接绘制条码 /// /// /// public static void DrawOneD(OneDData data, OneDDrawingOptions options) { if (options?.DrawGraphics == null) { throw new ArgumentNullException("OneDDrawingOptions.DrawGraphics"); } //if (options.ShowType != BarcodeShowType.Original) //{ // // 条码范围 // int width = options.ImageRect.Width - options.Margin.Horizontal; // int height = options.ImageRect.Height - options.Margin.Vertical; // if (data.Width != width) // { // data = Encode(data, width); // } // data.Height = height; //} DrawOneD(data, options.DrawGraphics, options); } /// /// 直接绘制条码 /// /// /// /// private static void DrawOneD(OneDData imageData, Graphics graphics, OneDDrawingOptions options) { // 条码范围 using (Image image = GetOneDSource(imageData, options)) { Rectangle rect = new Rectangle( options.ImageRect.Left + options.Margin.Left, options.ImageRect.Top + options.Margin.Top, //imageData.Width, //imageData.Height); options.ImageRect.Width - options.Margin.Horizontal, options.ImageRect.Height - options.Margin.Vertical); if (options.ShowType == BarcodeShowType.Zoom) { graphics.DrawImage(image, rect); } else if (options.ShowType == BarcodeShowType.Show) { ImageHelper.Show(image, graphics, rect, ContentAlignment.MiddleCenter, false); } else { ImageHelper.Show(image, graphics, rect, ContentAlignment.TopLeft, false); } } } /// /// 条码图片 /// /// /// /// /// public static Image GetOneDImage(string contents, OneDDrawingOptions options, OneDFormat format = OneDFormat.CODE_128) { if (options == null) { throw new ArgumentNullException("OneDDrawingOptions"); } if (options.ShowText) { Writer writer = null; if (formatWriter.ContainsKey(format)) { writer = formatWriter[format]; } if (writer == null) { return null; } BarcodeFormat barcodeFormat = formatMap[format]; EncodingOptions encodingOptions = new EncodingOptions(); encodingOptions.Width = options.ImageWidth - options.Margin.Horizontal; encodingOptions.Height = options.ImageHeight - options.Margin.Vertical; encodingOptions.PureBarcode = false; if (format == OneDFormat.EAN_13) { encodingOptions.GS1Format = true; } if (options.TextMargin.HasValue) { encodingOptions.Hints.Add(EncodeHintType.MARGIN, options.TextMargin); } AlternateBitmapRenderer render = new AlternateBitmapRenderer(); if (options.TextFont != null) { render.TextFont = options.TextFont; if (format == OneDFormat.EAN_8 || format == OneDFormat.EAN_13 || format == OneDFormat.UPC_E || format == OneDFormat.UPC_A) { if (options.DpiX.HasValue) { // zxing AlternateBitmapRenderer 创建图片没有设置分辨率 render.TextFont = new Font(options.TextFont.FontFamily, options.TextFont.Size * options.DpiX.Value / 96, options.TextFont.Style); } } } try { BitMatrix m = writer.encode(contents, barcodeFormat, encodingOptions.Width, encodingOptions.Height, encodingOptions.Hints); return render.Render(m, barcodeFormat, contents, encodingOptions); } catch (Exception ex) { //Font errorFont = new Font("Courier New", 9f, FontStyle.Regular); Font errorFont = render.TextFont ?? new Font("Courier New", 9f * (options.DpiX??96) / 96, FontStyle.Regular); Bitmap dataImage = new Bitmap(options.ImageWidth, options.ImageHeight); if (options != null && options.DpiX.HasValue) { dataImage.SetResolution(options.DpiX.Value, (options.DpiY) ?? options.DpiX.Value); } //Rectangle rectImage = new Rectangle(0, 0, options.ImageWidth, options.ImageHeight); using (Graphics g = Graphics.FromImage(dataImage)) { g.DrawString(ex.Message, errorFont, Brushes.Red, options.ImageRect); } return dataImage; } } OneDData data = Encode(contents, format); if (data == null) { return null; } // 条码范围 int width = options.ImageRect.Width - options.Margin.Horizontal; int height = options.ImageRect.Height - options.Margin.Vertical; data = Encode(data, width); data.Height = height; return GetOneDImage(data, options); } /// /// 条码图片 /// /// /// /// public static Image GetOneDImage(OneDData data, OneDDrawingOptions options) { if (options == null) { throw new ArgumentNullException("OneDDrawingOptions"); } if (options.ShowType == BarcodeShowType.Original) { return GetOneDSource(data, options); } Bitmap dataImage = new Bitmap(options.ImageRect.Width, options.ImageRect.Height); if (options.DpiX.HasValue) { dataImage.SetResolution(options.DpiX.Value, (options.DpiY) ?? options.DpiX.Value); } using (Graphics graphics = Graphics.FromImage(dataImage)) { graphics.Clear(options.BackColor); DrawOneD(data, graphics, options); } return dataImage; } /// /// 原始条码图片 /// /// /// /// public static Image GetOneDSource(OneDData data, OneDDrawingOptions options) { if (options == null) { throw new ArgumentNullException("OneDDrawingOptions"); } int height = data.Height; if (height < 1) { height = Math.Max(options.ImageRect.Height - options.Margin.Vertical, 1); } Bitmap dataImage = new Bitmap(data.Size, height); if (options != null && options.DpiX.HasValue) { dataImage.SetResolution(options.DpiX.Value, (options.DpiY) ?? options.DpiX.Value); } Rectangle rectImage = new Rectangle(0, 0, data.Size, height); BitmapData bmpData = dataImage.LockBits(rectImage, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); try { byte[] pixels = new byte[bmpData.Stride * bmpData.Height]; int index = 0; for (int x = 0; x < bmpData.Width; x++) { Color color = (data[x] ? options.ForeColor : options.BackColor); pixels[index++] = color.B; pixels[index++] = color.G; pixels[index++] = color.R; pixels[index++] = color.A; } for (int y = 1; y < bmpData.Height; y++) { Array.Copy(pixels, 0, pixels, y * bmpData.Stride, bmpData.Stride); } Marshal.Copy(pixels, 0, bmpData.Scan0, pixels.Length); } finally { dataImage.UnlockBits(bmpData); } return dataImage; } } }