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

Posted 风雨的叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二维码生成. 文字生成图片. 多张图片合并方法及临时合成图片并下载相关的知识,希望对你有一定的参考价值。

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

  

以上是关于二维码生成. 文字生成图片. 多张图片合并方法及临时合成图片并下载的主要内容,如果未能解决你的问题,请参考以下文章

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

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

用java怎么获得一张图片上的一个文字的坐标点 求高手解答

怎么把图片生成链接。

js多张图片合成一张图,canvas(海报图,将二维码和背景图合并) -----vue

两张图片合并生成