使用google zxing生成的二维码带有白色边框,显示在报告(使用Crystal Report 水晶报表)上时,由于空间有限造成二维码过小难以扫描识别。
通过将白色边框裁切掉,可以在有限的空间内最大化显示二维码。
using com.google.zxing; using com.google.zxing.common; using com.google.zxing.qrcode.decoder; using java.awt.image; using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sunway.Barcode { /// <summary> /// /// </summary> public static class BarcodeHelper { /// <summary> /// /// </summary> /// <param name="info"></param> /// <returns></returns> public static string CreateBarcode(string info) { string filePath = string.Empty; filePath = Guid.NewGuid().ToString() + ".png"; // try { MultiFormatWriter writer = new MultiFormatWriter(); Hashtable hints = new Hashtable(); hints.Add(EncodeHintType.CHARACTER_SET, "utf-8"); //编码 ErrorCorrectionLevel level = ErrorCorrectionLevel.H; hints.Add(EncodeHintType.ERROR_CORRECTION, level); //容错率 //hints.Add(EncodeHintType.MARGIN, 0); //二维码边框宽度,这里文档说设置0-4, ByteMatrix byteMatrix = writer.encode(info, BarcodeFormat.QR_CODE, 300, 300, hints); Bitmap bitmap = ToBitmap(byteMatrix); // bitmap.Save(filePath); } catch (Exception) { filePath = string.Empty; throw; } finally { } // return filePath; } /// <summary> /// 转换为位图 /// </summary> /// <param name="matrix"></param> /// <returns></returns> public static Bitmap ToBitmap(ByteMatrix matrix) { int width = matrix.Width; int height = matrix.Height; //32位ARGB格式 Bitmap bmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Color colorBlack = ColorTranslator.FromHtml("0xFF000000");//黑色 Color colorWhite = ColorTranslator.FromHtml("0xFFFFFFFF");//白色 // 二维矩阵转为一维像素数组,也就是一直横着排了 //Color[] pixels = new int[width * height]; bool isFirstBlackPoint = false; int startX = 0; int startY = 0; //循环内容矩阵,写入白、黑点 for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (matrix.get_Renamed(x, y) != -1)//返回白点/黑点 { if (!isFirstBlackPoint) { isFirstBlackPoint = true; startX = x;//二维码自带一个白色边框,边框内左上角是黑点,记录左上角的坐标点 startY = y; } } bmap.SetPixel(x, y, matrix.get_Renamed(x, y) != -1 ? colorBlack : colorWhite); } } #region 判断并截取 int PADDING_SIZE_MIN = 2; int x1 = startX - PADDING_SIZE_MIN; int y1 = startY - PADDING_SIZE_MIN; if (x1 < 0 || y1 < 0) { return bmap; } else { int w1 = width - x1 * 2; int h1 = height - y1 * 2; Bitmap bitmapQR = CutImage(bmap, new Rectangle(x1, y1, w1, h1)); return bitmapQR; } #endregion } /// <summary> /// 截取图片,指定截取区域(开始位置和长度/宽度) /// </summary> /// <param name="img"></param> /// <param name="rect"></param> /// <returns></returns> private static Bitmap CutImage(Image img, Rectangle rect) { Bitmap b = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(b); g.DrawImage(img, 0, 0, rect, GraphicsUnit.Pixel); g.Dispose(); return b; } } }