积跬步,聚小流------java信息生成图片

需求:


是在做证书的时候碰到的这个问题。
当时需求是可以进行在线打印证书,第一次进行的操作是直接打印html,并且已经排好版(用jqprint插件)进行打印,在打印时碰到了兼容的问题,另外由于背景图片加载较文字加载的慢,则出现先加载文字后出现图片的现象,则显的很不专业,遂采用了将信息转化为图片,然后直接打印图片,不论怎么样进行打印,都不会改变,而且可以导出图片,对图片进行更为精细的操作。

代码编写:


先不多说 先上代码:
package com.jzba.utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class ImgUtils {	
	
	private static int newWidth=0,newHeight=0,newX=0,newY=0;
	
	public static void main(String[] args) throws Exception{--1、本地测试
		String over="D:/zz/1/over.png";
		Color color = new Color(100,100,100);
		ImageUtil iu=new ImageUtil();
		Map map=iu.getImageSizeByBufferedImage("D:/zz/ceshi.png");--备注:见代码下方
		int width=(Integer)map.get("width");
		int height=(Integer)map.get("height");
		float bili=width/height;
		if (width>height) {
			newWidth=660;
			newHeight=height*660/width;
			newX=600;
			newY=1160+330-newHeight/2;
		}else{
			newHeight=660;
			newWidth=width*660/height;
			newY=1160;
			newX=600+330-newWidth/2;
		}
		//String temp1=createCard("D:/zz/1/background.png","D:/zz/1/ceshi.png","D:/zz/1/code.bmp","D:/zz/1/temp1.png",newX,newY,600,1210,newWidth,newHeight,250,250);
		String temp1=createCard("D:/zz/1/background.png","D:/zz/1/ceshi2.jpg","D:/zz/1/code.bmp","D:/zz/1/temp1.png",100,100,600,1210,newWidth,newHeight,250,250);
		ImageIcon imgIcon = new ImageIcon(temp1);
   		Image theImg = imgIcon.getImage();
   		int w = theImg.getWidth(null);
   		int h = theImg.getHeight(null);
   		BufferedImage bufImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
   		// 获取Graphics2D
   		Graphics2D g = bufImg.createGraphics();
   		g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
   		// 画图
   		bufImg = g.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
   		g.dispose();
   		g = bufImg.createGraphics();
   		g.setStroke(new BasicStroke(1));
   		g.drawImage(theImg, 0, 0, w, h, null);//背景图起始位置
   		g.setColor(color);
   		Font nf = loadFont("D:/zz/simhei.ttf",60);
   		Font nf2 = loadFont("D:/zz/simhei.ttf",50);
   	    g.setFont(nf);
   		g.drawString("秘  密",2500,1040);//
   		g.setFont(nf2);
   		g.drawString("秘  密",1920,1190);//
   		g.drawString("秘  密", 1920, 1290);//
   		g.drawString("秘  密", 1920, 1390);//
   		g.drawString("秘  密", 1920, 1490);//
   		g.drawString("秘  密 ", 1920, 1590);//
   		g.drawString("秘  密", 1920, 1700);//
   		g.drawString("秘  密", 1920, 1800);//
   		//释放对象
   		File tofile=new File(over);
   		ImageIO.write(bufImg, "png", tofile);
   		g.dispose();
	}
	/**
	 * 
	 * 将所要添加的图片整合在一起进行添加
	 * @param backsPath 背景图片的路径
	 * @param titleImgPath 缩略图图片的路径
	 * ...
	 * 
	 * @return toPath 合成后图片的路径
         * 
         * */
	
	
	public static String createCard(String backsPath,String titleImgPath,String codeImgPath,String toPath,int x,int y,int newx,int newy,int widthTitle,int heightTitle,int codeWidth,int codeHeight){
		 try {
			InputStream imageBack=new FileInputStream(backsPath);//背景图
		        InputStream imageTitle=new FileInputStream(titleImgPath);//缩略图图片
		        InputStream imageCode=new FileInputStream(codeImgPath);//二维码图片
		        BufferedImage backImg=ImageIO.read(imageBack);
		        BufferedImage titleImg=ImageIO.read(imageTitle);
		        BufferedImage codeImg=ImageIO.read(imageCode);
		        System.out.println("*****Graphics****"+backsPath);
		        Graphics g=backImg.getGraphics();
		        System.out.println("*****Graphics****1");
		        g.drawImage(titleImg,x,y,widthTitle,heightTitle,null);
		        System.out.println("*****Graphics****2");
		        g.drawImage(codeImg,newx,newy,codeWidth,codeHeight,null);
		        System.out.println("*****Graphics****3");
		        OutputStream outImage=new FileOutputStream(toPath);
		        System.out.println("*****Graphics****4");
//		        JPEGImageEncoder enc=JPEGCodec.createJPEGEncoder(outImage);--这里存在问题
//		        System.out.println("*****Graphics****5");--在window下可以,在linux下无法进行
//				enc.encode(backImg);
		        File tofile=new File(toPath);
		        ImageIO.write(backImg, "png", tofile);
//				System.out.println("*****"+backsPath);
		        imageBack.close();//关闭输出端口
		        imageTitle.close();
		        imageCode.close();
		        outImage.close();
		} catch (Exception e) {
				e.printStackTrace();
		}
		return toPath;
	}
	/**
	 * 将所要添加的文本信息整合在一起进行添加
	 * 
	 * 
	 * **/
	public static String addCardWord(String filePath,String toPath,int fontsize, Color markContentColor,String fontPath,String code,String type,String artist,
			String artname,String description,String material,String artisttype,String recordescription,String releaseDate,int codex,int codey,int typex,int typey,
			int artistx,int artisty,int artnamex,int artnamey,int descriptionx,int descriptiony,int materialx,int materialy,int artisttypex,int artisttypey,
			int recordescriptionx,int recordescriptiony)throws Exception{
		ImageIcon imgIcon = new ImageIcon(filePath);
   		Image theImg = imgIcon.getImage();
   		int w = theImg.getWidth(null);
   		int h = theImg.getHeight(null);
   		BufferedImage bufImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
   		// 获取Graphics2D
   		Graphics2D g = bufImg.createGraphics();
   		g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
   		// 画图
   		bufImg = g.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
   		g.dispose();
   		g = bufImg.createGraphics();
   		g.setStroke(new BasicStroke(1));
   		g.drawImage(theImg, 0, 0, w, h, null);//背景图起始位置
   		g.setColor(markContentColor);
   		Font nf = loadFont(fontPath,fontsize);
   	    g.setFont(nf);
   		g.drawString(code, codex, codey);
   		g.drawString(type, typex, typey);
   		g.drawString(artist, artistx, artisty);
   		g.drawString(artname, artnamex, artnamey);
   		g.drawString(description, descriptionx, descriptiony);
   		g.drawString(material, materialx, materialy);
   		g.drawString(artisttype, artisttypex, artisttypey);
   		g.drawString(recordescription, recordescriptionx, recordescriptiony);
   		//释放对象
   		File tofile=new File(toPath);
   		ImageIO.write(bufImg, "png", tofile);
   		g.dispose();
   		return toPath;
	}
	
	
	
	/**
	 * 向图片里面添加图片
	 * @param backsPath 背景图片路径
	 * @param upPath 添加图片路径
	 * @param toPath 生成图片路径
	 * @param x 所添加图片在背景图片上的横向位移,以左上角为标准
	 * @param y 所添加图片在背景图片上的竖向位移,以左上角为标准
	 * @param width 所添加图片的宽度
	 * @param height 所添加图片的高度
	 * @return toPath String 返回生成图片的路径
	 * 
	 * **/
    public static String addImg2Img(String backsPath,String upPath,String toPath,int x,int y,int width,int height){
        	   try {
	               InputStream imagein=new FileInputStream(backsPath);
	               InputStream imagein2=new FileInputStream(upPath);
	               BufferedImage image=ImageIO.read(imagein);//读取背景图片
	               BufferedImage image2=ImageIO.read(imagein2);//读取要添加的图片
	               Graphics g=image.getGraphics();//将背景图片作为画图面板
	               g.drawImage(image2,x,y,width,height,null);//在背景图片的基础上进行画图,将待添加图片加入
	               OutputStream outImage=new FileOutputStream(toPath);//打开导出图片路径
	               JPEGImageEncoder enc=JPEGCodec.createJPEGEncoder(outImage);
	               enc.encode(image);//将生成的图片输出
	               imagein.close();//关闭打开的导入、导出通道
	               imagein2.close();
	               outImage.close();
			   } catch (Exception e) {
			       e.printStackTrace();
			   }
        	   return toPath;
    }
    /**
	 * 向图片里面添加文字
	 * @param filePath 背景图片路径
	 * @param toPath 生成图片路径
	 * @param markContent 添加的文本内容
	 * @param fontsize 添加文本的字体大小
	 * @param markContentColor 添加文本的颜色
	 * @param fontPath 添加文本的字体
	 * @param x 所添加图片在背景图片上的横向位移,以左上角为标准
	 * @param y 所添加图片在背景图片上的竖向位移,以左上角为标准
	 * @return toPath String 返回生成图片的路径
	 * 
	 * **/
    public static String addWord2Img(String filePath,String toPath, String markContent,int fontsize, Color markContentColor,String fontPath,int x,int y) throws Exception {
	   		ImageIcon imgIcon = new ImageIcon(filePath);
	   		Image theImg = imgIcon.getImage();
	   		int w = theImg.getWidth(null);
	   		int h = theImg.getHeight(null);
	   		BufferedImage bufImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
	   		// 获取Graphics2D
	   		Graphics2D g = bufImg.createGraphics();
	   		g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
	   		// 画图
	   		bufImg = g.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
	   		g.dispose();
	   		g = bufImg.createGraphics();
	   		g.setStroke(new BasicStroke(1));
	   		g.drawImage(theImg, 0, 0, w, h, null);//背景图起始位置
	   		g.setColor(markContentColor);//给添加的文本进行颜色设置
	   		Font nf = loadFont(fontPath,fontsize);
	   	    g.setFont(nf);//对添加的文本进行字体和字体大小设置
	   		g.drawString(markContent, x, y);//将文本添加到图片指定的位置
	   		//释放对象
	   		File tofile=new File(toPath);//打开导出通道
	   		ImageIO.write(bufImg, "png", tofile);//进行画图
	   		g.dispose();
	   		return toPath;
  	}
    /**
	 * 对添加文本的字体和字体大小进行设置
	 * @param fontFileName 外部字体名
	 * @param fontsize 添加文本的字体大小
	 * @param markContentColor 添加文本的颜色
	 * @return dynamicFontPt Font 对文本的相应设置
	 * 
	 * **/
	public static Font loadFont(String fontFileName, float fontSize) throws Exception  //第一个参数是外部字体名,第二个是字体大小
	{
			File file = new File(fontFileName);
			FileInputStream aixing = new FileInputStream(file);
			Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, aixing);
			Font dynamicFontPt = dynamicFont.deriveFont(fontSize);
			aixing.close();
			return dynamicFontPt;
	}
	

}
备注:在代码中调用到了上一篇文章中获取图片尺寸的相应类,用在这里的目的是,针对不同的作品,可能是横向图片,也可能是竖条图片,为了保证图片不会变形失真,则将图片显示在固定的一个区域内, 像这里:

默认了一段660*660的区域,首先进行判定要添加图片是横条还是竖条,如果是横条,则宽度是大于高度的,则设置大的宽度为660,相应的根据比例:660/宽度=要求的高度/实际高度,则可以得到相应的高度值,而且此高度值肯定是小于660的,因为是横条,所以宽度的位移就是指定区域的相应位移,这里为600px,而高度位移,则应该是添加图片的左上角的位移,为背景图片的高度一半减去图片当前高度的一半;同理如果是竖条,则高度是大于宽度的,则设置大的高度为660,以此类推,得到相应的位移和尺寸。从而实现的效果是什么样子呢,我们来简单看下:
(这是高度大于宽度)
(这是宽度大于高度)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值