如何生成既带有图片又带有文字的二维码?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何生成既带有图片又带有文字的二维码?相关的知识,希望对你有一定的参考价值。

生成既带图片又带文字的二维码,需要二维码生成器,把文字和图片上传到生成器中,然后生成器将图片和文字转换为二维码,把二维码保存到手机,即可发送别人传阅。

二维条码/二维码可以分为堆叠式/行排式二维条码和矩阵式二维条码。堆叠式/行排式二维条码形态上是由多行短截的一维条码堆叠而成;矩阵式二维条码以矩阵的形式组成,在矩阵相应元素位置上用“点”表示二进制“1”,用“空”表示二进制“0”,“点”和“空”的排列组成代码。二维码的原理可以从矩阵式二维码的原理和行列式二维码的原理来讲述。

码上游二维码除了图片+文字,也可以再加入视频,语音,文档等内容,制作的二维码内容可随时修改,但二维码不变,修改内容后无需重新印刷二维码。还可以追踪用户的扫描数据,在后台就能看到扫描次数与时间。
进入码上游网站了解更多
参考技术A

二维码生成器中可以使用汉字,数字,字母,特殊符号以及网址生成二维码,如果需要将图片生成二维码的话,需要将图片上传到图片网站上或者是公司服务器中,把得到的图片地址放到二维码中进行生成,这样用微信扫描生成的二维码就会显示一张图片。步骤如下:

如果需要用大量的图片批量生成二维码,我们可以将图片上传到公司服务器,把得到的图片地址保存到TXT文本或者是Excel表中,然后将TXT文本或者Excel表导入到中琅二维码生成器中进行批量生成二维码。

 打开二维码生成器,在文档设置中根据实际纸张设置纸张尺寸和标签尺寸。

2. 将TXT文本导入到软件中,具体导入方法可以参考《在条码标签打印软件中怎么用网址链接批量生成二维码》,这里不再详述。

3. 在空白的标签上绘制一个二维码,双击绘制的二维码,在图形属性-数据源中点击“编辑”按钮,在打开的窗口中选择“数据库导入”数据类型,字段选择“图片地址”。

然用扫描软件扫描二维码就可以显示图片的。

二维码生成. 文字生成图片. 多张图片合并方法及临时合成图片并下载

package com.easyrail.eam.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

import com.easyrail.eam.itemManage.UpFileRoute;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 *二维码生成. 文字生成图片. 多张图片合并方法 
 */
public class CreateFile {
	private static final int BLACK = 0xFF000000;
	private static final int WHITE = 0xFFFFFFFF;

	private static final int WIDTH = 300;
	private static final int HEIGHT = 300;

	/**
	 * 把生成的二维码存入到图片中
	 * 
	 * @param matrix
	 *            zxing包下的二维码类
	 * @return
	 */
	public static BufferedImage toBufferedImage(BitMatrix matrix) {
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
			}
		}
		return image;
	}

	/**
	 * 生成二维码并写入文件
	 * 
	 * @param content
	 *            扫描二维码的内容
	 * @param format
	 *            图片格式 jpg
	 * @param file
	 *            文件
	 * @throws Exception
	 */
	public static void writeToFile(String content, String format, File file)
			throws Exception {
		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();

		@SuppressWarnings("rawtypes")
		Map hints = new HashMap();
		// 设置UTF-8, 防止中文乱码
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		// 设置二维码四周白色区域的大小
		hints.put(EncodeHintType.MARGIN, 1);
		// 设置二维码的容错性
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 画二维码
		BitMatrix bitMatrix = multiFormatWriter.encode(content,
				BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
		BufferedImage image = toBufferedImage(bitMatrix);
		if (!ImageIO.write(image, format, file)) {
			throw new IOException("不能生产此格式"
					+ format + " 的" + file);
		}
	}

	/**
	 * 把文字写成图片
	 * 
	 * @param str
	 *            文字
	 * @param filePath
	 *            产生的图片位置
	 * @param width
	 *            宽
	 * @param font 字体设置
	 * @param filename 图片名称(需带后缀)
	 * @return
	 * @throws IOException 
	 */
	public static BufferedImage create(String str, String filePath, int width,
			Font font, String filename) throws IOException {
		// 获取font的样式应用在str上的整个矩形
		Rectangle2D r = font.getStringBounds(str, new FontRenderContext(
				AffineTransform.getScaleInstance(1, 1), false, false));
//		int a=(int) Math.round(r.getWidth()%WIDTH==0?r.getWidth()/WIDTH:r.getWidth()/WIDTH+1)+1;//这里可以自动获取宽度并根据照片宽度进行换行输出文字
		String[] arrys=str.split("#");
		int a=arrys.length;
		int stringlength=(int) Math.round(r.getWidth()/str.length());
		int unitHeight = (int) Math.floor(r.getHeight());// 获取单个字符的高度
		int height = unitHeight*(a+1) + 3*a;// 把单个字符的高度+3保证高度绝对能容纳字符串作为图片的高度
		String fileName = filename;
		String path = filePath + "/" + fileName;
		File file = new File(path);
		BufferedImage bi = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);

		Graphics2D g2 = (Graphics2D) bi.createGraphics();
		g2.setBackground(Color.WHITE);
		g2.clearRect(0, 0, width, height);
		
		g2.setFont(font);
		g2.setPaint(Color.black);
		FontRenderContext context = g2.getFontRenderContext();
		Rectangle2D bounds = font.getStringBounds(str, context);
		double x = (width - (bounds.getWidth())/a) / 3;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		int startX = 0;
		int startY = (int)(bounds.getHeight()+3);
		startX = (int)x;
		for (int i = 0; i <a; i++) {
			g2.drawString(arrys[i], startX, startY);
			/*if (i == a-1) {//画文字
				g2.drawString(str.substring((int)(r.getWidth()/a)*i/stringlength, str.length()), startX, startY);
			} else {
				g2.drawString(str.substring((int)((r.getWidth()/a)*i/stringlength), (int)((r.getWidth()/a)*(i+1)/stringlength)), startX, startY);
			}*/
			startY = startY + (int)(bounds.getHeight()+3);
		}
//		try {
//			ImageIO.write(bi, "jpg", file);
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
		return bi;
	}

	/**
	 * 图片拼接
	 * 
	 * @param files
	 *            要拼接的文件列表
	 * @param type
	 *            1 横向拼接, 2 纵向拼接
	 * @param filePath 生成的路径
	 * @param name 图片的名称(需带后缀)
	 * @return
	 */
	public static boolean merge(String[] files, int type, String filePath,String name) {

		int len = files.length;
		if (len < 1) {
			System.out.println("图片数量小于1");
			return false;
		}

		File[] src = new File[len];
		BufferedImage[] images = new BufferedImage[len];
		int[][] ImageArrays = new int[len][];
		for (int i = 0; i < len; i++) {
			try {
				src[i] = new File(files[i]);
				images[i] = ImageIO.read(src[i]);
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
			int width = images[i].getWidth();
			int height = images[i].getHeight();
			ImageArrays[i] = new int[width * height];// 从图片中读取RGB
			ImageArrays[i] = images[i].getRGB(0, 0, width, height,
					ImageArrays[i], 0, width);
		}

		int newHeight = 0;
		int newWidth = 0;
		for (int i = 0; i < images.length; i++) {
			// 横向
			if (type == 1) {
				newHeight = newHeight > images[i].getHeight() ? newHeight
						: images[i].getHeight();
				newWidth += images[i].getWidth();
			} else if (type == 2) {// 纵向
				newWidth = newWidth > images[i].getWidth() ? newWidth
						: images[i].getWidth();
				newHeight += images[i].getHeight();
			}
		}

		System.out.println("拼接后图像宽度:" + newWidth);
		System.out.println("拼接后图像高度:" + newHeight);
		if (type == 1 && newWidth < 1) {
			System.out.println("拼接后图像宽度小于1");
			return false;
		}
		if (type == 2 && newHeight < 1) {
			System.out.println("拼接后图像高度小于1");
			return false;
		}

		// 生成新图片
		try {
			BufferedImage ImageNew = new BufferedImage(newWidth, newHeight,
					BufferedImage.TYPE_INT_RGB);
			int height_i = 0;
			int width_i = 0;
			for (int i = 0; i < images.length; i++) {
				if (type == 1) {
					ImageNew.setRGB(width_i, 0, images[i].getWidth(),
							newHeight, ImageArrays[i], 0, images[i].getWidth());
					width_i += images[i].getWidth();
				} else if (type == 2) {
					ImageNew.setRGB(0, height_i, newWidth,
							images[i].getHeight(), ImageArrays[i], 0, newWidth);
					height_i += images[i].getHeight();
				}
			}
			File outFile = new File(filePath,name);
			if(!outFile.isDirectory()){
				outFile.mkdirs();
			}
			ImageIO.write(ImageNew, "jpg", outFile);// 写图片
			return true;

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	public static InputStream pin(BufferedImage image,String file,int type, String filePath,String name){
		File src = new File(file);
		BufferedImage[] images = new BufferedImage[2];
		int[][] ImageArrays = new int[2][];
		try {
			images[0] = ImageIO.read(src);
			images[1]=image;
		} catch (Exception e) {
			e.printStackTrace();
		}
		for(int i=0;i<2;i++){
			int width = images[i].getWidth();
			int height = images[i].getHeight();
			ImageArrays[i] = new int[width * height];// 从图片中读取RGB
			ImageArrays[i] = images[i].getRGB(0, 0, width, height,
					ImageArrays[i], 0, width);
		}
		int newHeight = 0;
		int newWidth = 0;
		for (int i = 0; i < images.length; i++) {
			// 横向
			if (type == 1) {
				newHeight = newHeight > images[i].getHeight() ? newHeight
						: images[i].getHeight();
				newWidth += images[i].getWidth();
			} else if (type == 2) {// 纵向
				newWidth = newWidth > images[i].getWidth() ? newWidth
						: images[i].getWidth();
				newHeight += images[i].getHeight();
			}
		}

		System.out.println("拼接后图像宽度:" + newWidth);
		System.out.println("拼接后图像高度:" + newHeight);
		if (type == 1 && newWidth < 1) {
			System.out.println("拼接后图像宽度小于1");
		}
		if (type == 2 && newHeight < 1) {
			System.out.println("拼接后图像高度小于1");
		}

		// 生成新图片
		try {
			BufferedImage ImageNew = new BufferedImage(newWidth, newHeight,
					BufferedImage.TYPE_INT_RGB);
			int height_i = 0;
			int width_i = 0;
			for (int i = 0; i < images.length; i++) {
				if (type == 1) {
					ImageNew.setRGB(width_i, 0, images[i].getWidth(),
							newHeight, ImageArrays[i], 0, images[i].getWidth());
					width_i += images[i].getWidth();
				} else if (type == 2) {
					ImageNew.setRGB(0, height_i, newWidth,
							images[i].getHeight(), ImageArrays[i], 0, newWidth);
					height_i += images[i].getHeight();
				}
			}
			File outFile = new File(filePath,name);
			if(!outFile.isDirectory()){
				outFile.mkdirs();
			}
			InputStream is=null;
			ByteArrayOutputStream bs=new ByteArrayOutputStream();
			ImageOutputStream stream;
			ImageNew.flush();
			try {
				stream=ImageIO.createImageOutputStream(bs);
				ImageIO.write(ImageNew, "png", stream);
				is=new ByteArrayInputStream(bs.toByteArray());
			} catch (Exception e) {
				e.printStackTrace();
			}
			return is;
//			ImageIO.write(ImageNew, "jpg", outFile);// 写图片

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	public static void main(String[] args) throws Exception {
//		String[] files = { "E:/google.jpg", "E:/google2.jpg" };
//		File qrcFile = new File("E:/", "google.jpg");
//		writeToFile("www.google.com.hk", "jpg", qrcFile);
//		create("编号:ZZD-XN-1-ZJ-01#名称:美的家用变频空调#类型:吊顶式新风空调箱#厂家:美的空调#型号:SSD-0002-00009", 
//				"E:/", WIDTH, new Font("微软雅黑", Font.LAYOUT_NO_LIMIT_CONTEXT, 20),
//				"google2.jpg");
//		merge(files, 2, "E:/heihei","789.jpg");
		String str="\\fileManage\\fileUpload\\equipQRCode\\SB-0002.png";
		System.out.println(str.substring(str.lastIndexOf(UpFileRoute.equipQRCode)+12));
	}
	
	//临时拼接好两张图片并输出到前台进行下载
	@RequestMapping(value="/downQRCode")
	public ModelAndView downQRCode(HttpServletRequest request,HttpServletResponse response,Long id) throws Exception{
		Equip equip=equipService.selectEquipDetail(id);
		String name=equip.getUrl().substring(equip.getUrl().lastIndexOf(UpFileRoute.equipQRCode)+12);
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;

		String ctxPath = fileUploadPath+
				"\\"+UpFileRoute.equipQRCode+"\\";
		BufferedImage image=CreateFile.create("编号:"+equip.getNum()+"#名称:"+equip.getEquipName()+"#类型:"+equip.getEquipTypeName()+"#厂家:"+equip.getEquipFactory()+"#型号:"+equip.getEquipModel()+"", 
				"E:/", 300, new Font("微软雅黑", Font.LAYOUT_NO_LIMIT_CONTEXT, 20),
				"google2.jpg");
		String downLoadPath = ctxPath +name;
		InputStream input=CreateFile.pin(image, downLoadPath, 2, "D:/", name);
		long fileLength = input.available();//这里长度必须是两个图片文件的长度,否则会出现黑色图片
		response.setContentType("multipart/form-data");
		response.setHeader("Content-disposition", "attachment; filename="
				+ new String(name.getBytes("utf-8"), "ISO8859-1"));
		response.setHeader("Content-Length", String.valueOf(fileLength));
		
		bis = new BufferedInputStream(input);
		bos = new BufferedOutputStream(response.getOutputStream());
		byte[] buff = new byte[2048];
		int bytesRead;
		while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
			bos.write(buff, 0, bytesRead);
		}
		bis.close();
		bos.close();
		return null;
	}
}

  

以上是关于如何生成既带有图片又带有文字的二维码?的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发-生成二维码图片附中间带有小图标二维码(QRCode)

生成一张带有logo的二维码图片

文字如何生成二维码?

如何生成葵花码二维码图片

如何在二维码内容中添加图片内容

二维码生成,二维码中嵌套图片,文字生成图片