using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Threading.Tasks; using SkiaSharp; using ZXing; using ZXing.Common; using ZXing.QrCode.Internal; namespace 常用工具集.Utility.Qrcode { public class BarCodeUtils { public static SKBitmap EncodeBarCode(BarcodeFormat barcodeFormat, string message, int widthPixels, int hightPixels, out string svg) { Dictionary hints = new Dictionary(); hints.Add(EncodeHintType.CHARACTER_SET, "utf-8"); hints.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); hints.Add(EncodeHintType.MARGIN, 1); BitMatrix matrix = new MultiFormatWriter().encode(message, barcodeFormat, widthPixels, hightPixels, hints); //matrix = deleteWhite(matrix);//删除白边 SKBitmap bitmap = new SKBitmap(matrix.Width, matrix.Height); SKCanvas canvas = new SKCanvas(bitmap); canvas.Clear(); SKPaint paint = new SKPaint() { Color = SKColors.Black, IsAntialias = true, Style = SKPaintStyle.Fill }; StringBuilder sb = new StringBuilder(); sb.AppendLine(""); sb.AppendLine($""); sb.AppendLine(""); bool[,] handled = new bool[matrix.Width, matrix.Height];//默认全部false for (int x = 0; x < matrix.Width; x++) { for (int y = 0; y < matrix.Height; y++) { if (matrix[x, y] && !handled[x, y]) { //从当前位置找矩形区域 FindRect(x, y, matrix, ref handled, out int width, out int height); //x从x到x+width //y从y到y+height //这些区域是已处理的 for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { handled[x + i, y + j] = true; } } sb.AppendLine($""); canvas.DrawRect(x, y, width, height, paint); } } } sb.AppendLine(""); svg = sb.ToString(); canvas.Dispose(); return bitmap; //BarcodeWriter writer = new BarcodeWriter(); ////使用ITF 格式,不能被现在常用的支付宝、微信扫出来 ////如果想生成可识别的可以使用 CODE_128 格式 ////writer.Format = BarcodeFormat.ITF; //writer.Format = barcodeFormat; //EncodingOptions options = new EncodingOptions() //{ // Width = widthPixels, // Height = hightPixels, // Margin = 2 //}; //writer.Options = options; //Bitmap map = writer.Write(message); //return map; } /// /// 找到未处理的矩形区域 /// /// /// /// /// /// /// private static void FindRect(int x, int y, BitMatrix matrix, ref bool[,] handled, out int width, out int height) { width = 1; height = 1; bool flag = false; int maxOffset = FindXMax(matrix, x, y, ref handled); A: if (maxOffset == 0) { return; } while (true) { height++; if ((y + height) >= matrix.Height) { break; } if (!matrix[x, y + height] || handled[x, y + height]) { break; } bool allTrue = true;//默认最后一行全是true for (int i = 0; i < maxOffset; i++) { if (!matrix[x + i, y + height]) { allTrue = false; break; } if (handled[x + i, y + height]) { allTrue = false; break; } } if (allTrue) { flag = true; } else { if (flag || height == 2) { height--; break; } maxOffset--; flag = false; goto A; } } width = maxOffset + 1; } private static int FindXMax(BitMatrix matrix, int x, int y, ref bool[,] handled) { int offset = 0; while (true) { if ((x + offset) > matrix.Width) { break; } if (!matrix[x + offset, y]) { offset--; break; } offset++; } return offset; } public static SKBitmap EncodeBarCode(string message, int widthPixels, int hightPixels, out string svg) { return EncodeBarCode(BarcodeFormat.CODE_128, message, widthPixels, hightPixels, out svg); } public static SKBitmap EncodeBarCode(string msg, out string svg) { return EncodeBarCode(msg, 960, 500, out svg); } } }