二话不说,直接上代码。
/**
* <p class="detail">
* 功能:二维码批量生成
* </p>
*
* @author Moha
* @ClassName Qcode Production.
* @Version V1.0.
* @date 2017.08.24 14:58:03
*/
public class QcodesProduction {
private static final Logger LOGGER = LoggerFactory.getLogger(QcodesProduction.class);
// 图片宽度的一般
private static final int IMAGE_WIDTH = 100;
private static final int IMAGE_HEIGHT = 100;
private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
private static final int FRAME_WIDTH = 2;
private static final int Q_WIDTH = 760;
private static final int Q_HEIGHT = 760;
private static final String BACKGROUNDPIC = "img/title.jpg";
private static final String LOGO = "img/logo.jpg";
private static final String MicrosoftAccorblack = "msyh.ttf";
private static final int BPIC_WIDTH = 1500;
// 二维码写码器
private static MultiFormatWriter mutiWriter = new MultiFormatWriter();
//本地调试专用
//二维码业务代码
public static void encode(String content,
String srcImagePath, String destImagePath) {
try {
// ImageIO.write 参数 1、BufferedImage 2、输出的格式 3、输出的文件
BufferedImage image = genBarcode(content, Q_WIDTH, Q_HEIGHT, srcImagePath);//二维码
//背景图
BufferedImage bg = ImageIO.read(QcodesProduction.class.getClassLoader().getResourceAsStream(BACKGROUNDPIC));
Graphics2D g = bg.createGraphics();
//将二维码放在背景图上 坐标x:370 y:980
g.drawImage(image, 370, 980, Q_WIDTH, Q_HEIGHT, null);
//设置文字
g.setColor(Color.BLACK);
g.setFont(new Font("微软雅黑", Font.BOLD, 50));
g.drawString("xxxxxxx公司", 750, 200);
g.dispose();
image.flush();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", new File(destImagePath));
//ImageIO.write(image, "jpg", baos);
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println(simpleDateFormat.format(new Date()));
QcodesProduction
.encode(
"110",
"img/logo.jpg", "D:\\2013-01.jpg");
System.out.println(simpleDateFormat.format(new Date()));
}
/**
* @param contents 二维码显示的需要的参数
*/
public static java.util.List<String> encode(java.util.List<Map<String, Object>> contents) {
java.util.List<String> urlList = new ArrayList<>();
for (Map<String, Object> content : contents) {
BufferedImage qCode = null;
BufferedImage bg = null;
try {
if (content.get("email") == null || content.get("email").toString().isEmpty()) {
LOGGER.error("null email");
continue;
}
if (content.get("enterpriseId") == null || content.get("enterpriseId").toString().isEmpty()) {
LOGGER.error("null enterpriseId");
continue;
}
String nameEN = content.get("nameEN") == null ? "" : content.get("nameEN").toString();
String nameCN = content.get("nameCN") == null ? "" : content.get("nameCN").toString();
if (nameEN.isEmpty() && nameCN.isEmpty()) {
LOGGER.error("name is empty");
}
qCode = genBarcode(content.get("email").toString(), Q_WIDTH, Q_HEIGHT, LOGO);//二维码
bg = ImageIO.read(QcodesProduction.class.getClassLoader().getResourceAsStream(BACKGROUNDPIC));//背景图
Graphics2D g = bg.createGraphics();
//将二维码放在背景图上 坐标x:370 y:980
g.drawImage(qCode, 370, 980, Q_WIDTH, Q_HEIGHT, null);
//加载本地字体
Font font = Font.createFont(Font.TRUETYPE_FONT, QcodesProduction.class.getClassLoader().getResourceAsStream(MicrosoftAccorblack));
if (!nameCN.isEmpty()) {
//设置文字
//1.大字
g.setColor(Color.BLACK);
font = font.deriveFont(Font.BOLD, 50);
g.setFont(font);
int widhss = g.getFontMetrics().stringWidth(nameCN);
g.drawString(nameCN, (BPIC_WIDTH - widhss) / 2, nameEN.isEmpty() ? 2180 : 2140);
//2.小字
g.setColor(Color.BLACK);
font = font.deriveFont(Font.PLAIN, 40);
g.setFont(font);
twolineENnameDeal(2200, 2250, nameEN, g, 60);
} else {
//无中文名
//设置文字
//1.大字
g.setColor(Color.BLACK);
font = font.deriveFont(Font.PLAIN, 50);
g.setFont(font);
twolineENnameDeal(2180, 2230, nameEN, g, 45);
}
g.dispose();
bg.flush();
qCode.flush();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bg, "png", new File("D:\\2017-09.jpg"));//本地调试使用
//ImageIO.write(bg, "jpg", baos);
baos.flush();
} catch (WriterException | IOException | FontFormatException e) {
LOGGER.error("Qcode production failed enterpriseid:" + content.get("enterpriseId"), e);
}
}
return urlList;
}
/**
* @param y1 第一行的高度y坐标
* @param y2 第二行的高度y坐标
* @param nameEN 英文名称
* @param length 基准字符串长度
*/
private static void twolineENnameDeal(int y1, int y2, String nameEN, Graphics2D g, int length) {
if (nameEN.length() <= length) {
int widhss = g.getFontMetrics().stringWidth(nameEN);
g.drawString(nameEN, (BPIC_WIDTH - widhss) / 2, 2200);
} else {
String onelineName = nameEN;
String twolineName = "";
while (true) {
int index = onelineName.lastIndexOf(" ");
if (index <= 0) {
//字符串无空格
onelineName = nameEN.substring(0, 45);
twolineName = nameEN.substring(45);
} else {
//有空格
onelineName = nameEN.substring(0, index);
twolineName = nameEN.substring(index);
}
if (onelineName.length() <= 45) {
//1
int widhssa = g.getFontMetrics().stringWidth(onelineName);
g.drawString(onelineName, (BPIC_WIDTH - widhssa) / 2, y1);
//2
int widhssb = g.getFontMetrics().stringWidth(twolineName);
g.drawString(twolineName, (BPIC_WIDTH - widhssb) / 2, y2);
break;
}
}
}
}
/**
* 得到BufferedImage
*
* @param content 二维码显示的文本
* @param width 二维码的宽度
* @param height 二维码的高度
* @param srcImagePath 中间嵌套的图片
* @return
* @throws WriterException
* @throws IOException
*/
private static BufferedImage genBarcode(String content, int width,
int height, String srcImagePath) throws WriterException,
IOException {
// 读取源图像
BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH,
IMAGE_HEIGHT, true);
int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
for (int i = 0; i < scaleImage.getWidth(); i++) {
for (int j = 0; j < scaleImage.getHeight(); j++) {
srcPixels[i][j] = scaleImage.getRGB(i, j);
}
}
java.util.Hashtable hint = new java.util.Hashtable();
hint.put(EncodeHintType.CHARACTER_SET, "utf-8");
//二维码复杂度
hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
//二维码内边距
//hint.put(EncodeHintType.MARGIN,1);
// 生成二维码
BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE,
width, height, hint);
//matrix = deleteWhite(matrix);//删除白边
// 二维矩阵转为一维像素数组
int halfW = matrix.getWidth() / 2;
int halfH = matrix.getHeight() / 2;
int[] pixels = new int[width * height];
for (int y = 0; y < matrix.getHeight(); y++) {
for (int x = 0; x < matrix.getWidth(); x++) {
// 读取图片
if (x > halfW - IMAGE_HALF_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH
&& y < halfH + IMAGE_HALF_WIDTH) {
pixels[y * width + x] = srcPixels[x - halfW
+ IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
}
// 在图片四周形成边框
else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
- IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
pixels[y * width + x] = 0xfffffff;
} else {
// 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;
pixels[y * width + x] = matrix.get(x, y) ? 0xff000000
: 0xfffffff;
}
}
}
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
image.getRaster().setDataElements(0, 0, width, height, pixels);
return image;
}
/**
* 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标
*
* @param srcImageFile 源文件地址
* @param height 目标高度
* @param width 目标宽度
* @param hasFiller 比例不对时是否需要补白:true为补白; false为不补白;
* @throws IOException
*/
private static BufferedImage scale(String srcImageFile, int height,
int width, boolean hasFiller) throws IOException {
double ratio = 0.0; // 缩放比例
BufferedImage srcImage = ImageIO.read(QcodesProduction.class.getClassLoader().getResourceAsStream(srcImageFile));
Image destImage = srcImage.getScaledInstance(width, height,
BufferedImage.SCALE_SMOOTH);
// 计算比例
if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
if (srcImage.getHeight() > srcImage.getWidth()) {
ratio = (new Integer(height)).doubleValue()
/ srcImage.getHeight();
} else {
ratio = (new Integer(width)).doubleValue()
/ srcImage.getWidth();
}
AffineTransformOp op = new AffineTransformOp(AffineTransform
.getScaleInstance(ratio, ratio), null);
destImage = op.filter(srcImage, null);
}
if (hasFiller) {// 补白
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphic = image.createGraphics();
graphic.setColor(Color.white);
graphic.fillRect(0, 0, width, height);
if (width == destImage.getWidth(null))
graphic.drawImage(destImage, 0, (height - destImage
.getHeight(null)) / 2, destImage.getWidth(null),
destImage.getHeight(null), Color.white, null);
else
graphic.drawImage(destImage,
(width - destImage.getWidth(null)) / 2, 0, destImage
.getWidth(null), destImage.getHeight(null),
Color.white, null);
graphic.dispose();
destImage = image;
}
return (BufferedImage) destImage;
}
}