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