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;
}
}
}