JAVA工具类之多图片合成与图片添加文字
程序员文章站
2024-03-24 23:02:04
...
应公司需要,需要给每个客户生成个性的微信图片二维码,涉及到背景图片、微信带参二维码和微信头像的合成,并将微信你昵称添加在上面。
效果如下:
图片实现代码,需依赖JAVA图片处理工具类(放大、缩小)
PictureMerge.java
package com.bigbigbu.wx.utils;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
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.Date;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import org.apache.commons.lang3.StringUtils;
/**
* <p>Title: PictureMerge</p>
* <p>Description: 图片合并</p>
* <p>Company: DINGGE</p>
* @author FANQIBU
* @date 2017年12月1日
*/
public class PictureMerge {
/**
* @param fileUrl
* 文件绝对路径或相对路径
* @return 读取到的缓存图像
* @throws IOException
* 路径错误或者不存在该文件时抛出IO异常
*/
public static BufferedImage getBufferedImage(String fileUrl)throws IOException {
File f = new File(fileUrl);
return ImageIO.read(f);
}
/**
* @param savedImg
* 待保存的图像
* @param saveDir
* 保存的目录
* @param fileName
* 保存的文件名,必须带后缀,比如 "beauty.jpg"
* @param format
* 文件格式:jpg、png或者bmp
* @return
*/
public static boolean saveImage(BufferedImage savedImg, String saveDir,String fileName, String format) {
boolean flag = false;
// 先检查保存的图片格式是否正确
String[] legalFormats = { "jpg", "JPG", "png", "PNG", "bmp", "BMP" };
int i = 0;
for (i = 0; i < legalFormats.length; i++) {
if (format.equals(legalFormats[i])) {
break;
}
}
if (i == legalFormats.length) { // 图片格式不支持
System.out.println("不是保存所支持的图片格式!");
return false;
}
// 再检查文件后缀和保存的格式是否一致
String postfix = fileName.substring(fileName.lastIndexOf('.') + 1);
if (!postfix.equalsIgnoreCase(format)) {
System.out.println("待保存文件后缀和保存的格式不一致!");
return false;
}
String fileUrl = saveDir + fileName;
File file = new File(fileUrl);
try {
flag = ImageIO.write(savedImg, format, file);
} catch (IOException e) {
e.printStackTrace();
}
return flag;
}
/**
* 待合并的两张图必须满足这样的前提,如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
* mergeImage方法不做判断,自己判断。
*
* @param img1
* 待合并的第一张图
* @param img2
* 带合并的第二张图
* @param isHorizontal
* 为true时表示水平方向合并,为false时表示垂直方向合并
* @return 返回合并后的BufferedImage对象
* @throws IOException
*/
public static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2, boolean isHorizontal,int startX, int startY)throws IOException {
int w1 = img1.getWidth();
int h1 = img1.getHeight();
int w2 = img2.getWidth();
int h2 = img2.getHeight();
// 从图片中读取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
int[] ImageArrayTwo = new int[w2 * h2];
ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);
// 生成新图片
BufferedImage DestImage = null;
if (isHorizontal) { // 水平方向合并
DestImage = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
DestImage.setRGB(startX,startY, w2, h2, ImageArrayTwo, 0, w2); // 设置下半部分的RGB
} else { // 垂直方向合并
DestImage = new BufferedImage(w1, h1 + h2,BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2); // 设置下半部分的RGB
}
return DestImage;
}
/**
* <p>Title: getImageStream</p>
* <p>Description: 获取图片InputStream</p>
* @param destImg
* @return
*/
public static InputStream getImageStream( BufferedImage destImg){
InputStream is = null;
BufferedImage bi = destImg;
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageOutputStream imOut;
try {
imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(bi, "png",imOut);
is= new ByteArrayInputStream(bs.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
/**
* <p>Title: drawTextInImg</p>
* <p>Description: 图片上添加文字业务需求要在图片上添加水</p>
* @param filePath
* @param outPath
* @param text
*/
public static BufferedImage drawTextInImg(BufferedImage bimage,FontText text,int left,int top) {
Graphics2D g = bimage.createGraphics();
g.setColor(getColor(text.getWm_text_color()));
g.setBackground(Color.white);
Font font = new Font(text.getWm_text_font(), Font.BOLD,
text.getWm_text_size());
g.setFont(font);
//g.drawBytes(text.getText().getBytes(), 0,text.getText().getBytes().length, left-50, top-50);
g.drawString(text.getText(), left, top);
g.dispose();
return bimage;
}
// color #2395439
public static Color getColor(String color) {
if (color.charAt(0) == '#') {
color = color.substring(1);
}
if (color.length() != 6) {
return null;
}
try {
int r = Integer.parseInt(color.substring(0, 2), 16);
int g = Integer.parseInt(color.substring(2, 4), 16);
int b = Integer.parseInt(color.substring(4), 16);
return new Color(r, g, b);
} catch (NumberFormatException nfe) {
return null;
}
}
/**
* <p>Title: myQr</p>
* <p>Description: 生成我的二维码</p>
* @param headurl
* @param wxqr
* @return
*/
/**
* <p>Title: myQr</p>
* <p>Description: </p>
* @param openid
* @param headurl
* @param wxqr
* @return
*/
public static BufferedImage myQr(String nickname,String openid,String headurl,String wxqr) {
Properties pro = new Properties();
try {
pro.load(PictureMerge.class.getResourceAsStream("/http.properties"));
} catch (IOException e) {
e.printStackTrace();
}
// 读取待合并的文件
BufferedImage bi1 = null;
BufferedImage bi2 = null;
BufferedImage bi3 = null;
// 调用mergeImage方法获得合并后的图像
BufferedImage destImg = null;
String baseurl=PictureMerge.class.getResource("/").toString().replace("file:/", "");
if("0".equals(pro.get("wx.debug"))){
baseurl="/"+baseurl;
//baseurl="/src";
}
/*System.out.println("用户Openid:"+openid);
System.out.println("用户头像:"+headurl);
System.out.println("用户带参二维码:"+wxqr);
System.out.println("推广二维码模板:"+baseurl+"qrimg/qrTemplate.png");*/
try {
File fTemp = new File(baseurl+"qrimg/qrTemplate.png");
//File uTemp = new File(baseurl+"qrimg/"+openid+".png");
File uTemp = new File(baseurl+"qrimg/"+new Date().getTime()+".png");
System.out.println("OLD模板:"+fTemp.getName()+"NEW模板:"+uTemp.getName());
FileUtils.copyFileUsingFileChannels(fTemp, uTemp);
bi1 = ImageIO.read(uTemp);
uTemp.delete();
/**缓存推广二维码*/
InputStream qrInputStream = FileUtils
.getInputStreamByGet(wxqr);
bi2 =ImageUtil.zoomOutImage( ImageIO.read(qrInputStream),1,120,120);
/**缓存头像*/
if(StringUtils.isEmpty(headurl)){
headurl=baseurl+"qrimg/commonhead.png";
}
InputStream headInputStream = FileUtils
.getInputStreamByGet(headurl);
BufferedImage headImage=ImageIO.read(headInputStream);
bi3 =ImageUtil.zoomOutImage( headImage,-1,113,113);
} catch (IOException e) {
e.printStackTrace();
}
// 调用mergeImage方法获得合并后的图像
try {
int w1 = bi1.getWidth();
int fw1=w1;
int h1 = bi1.getHeight();
int fh1=h1;
int w2 = bi2.getWidth();
int fw2=w2;
int h2 = bi2.getHeight();
int fh2=h2;
destImg = mergeImage(bi1, bi2, true,(w1/2-w2/2),(h1/2-h2/2-60));
w1 = destImg.getWidth();
h1 = destImg.getHeight();
w2 = bi3.getWidth();
h2 = bi3.getHeight();
System.out.println(w2+"==="+h2);
int startX=w1/4-w2/4+w2*3-40;
int startY=h1/2-h2/2-h2*4-20;
destImg = mergeImage(destImg, bi3, true,startX,startY);
/**为图片添加昵称*/
destImg=drawTextInImg(destImg, new FontText(EmojiUtils.filterName(nickname),3, "#FFFFF", 25, "宋体"),(fw1/2-fw2/2)*3-80,(fh1/2-fh2-150));
} catch (IOException e) {
e.printStackTrace();
}
return destImg;
// 保存图像
//saveImage(destImg, baseurl, "qrimg/luguo.png", "png");
//System.out.println("水平合并完毕!");
}
public static void main(String[] args) {
String baseurl=new PictureMerge().getClass().getResource("/").toString().replace("file:/", "");
BufferedImage destImg = myQr("LC[0xf0][0x9f][0x98][0x8a]","oIhOc0hzx-ljAH_QQOTD2ImoylvQ","http://wx.qlogo.cn/mmopen/PiajxSqBRaELjvm6Ld5SUYzfRE0vjlDYa81AnkAjAS5Ifo4vdAZpoJicHGsYDEDTP8icecibDtkX92icbRNic7IsumSA/0",
"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQGM8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyeElmZTlYUDE4cV8xMDAwME0wN0QAAgR5GSJaAwQAAAAA");
saveImage(destImg, baseurl, "qrimg/luguo.png", "png");
}
}
FontText .java
package com.lh.wx.utils;
public class FontText {
private String text;
private int wm_text_pos;
private String wm_text_color;
private Integer wm_text_size;
private String wm_text_font;//字体 “黑体,Arial”
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getWm_text_pos() {
return wm_text_pos;
}
public void setWm_text_pos(int wm_text_pos) {
this.wm_text_pos = wm_text_pos;
}
public String getWm_text_color() {
return wm_text_color;
}
public void setWm_text_color(String wm_text_color) {
this.wm_text_color = wm_text_color;
}
public Integer getWm_text_size() {
return wm_text_size;
}
public void setWm_text_size(Integer wm_text_size) {
this.wm_text_size = wm_text_size;
}
public String getWm_text_font() {
return wm_text_font;
}
public void setWm_text_font(String wm_text_font) {
this.wm_text_font = wm_text_font;
}
public FontText(String text, int wm_text_pos, String wm_text_color,
Integer wm_text_size, String wm_text_font) {
super();
this.text = text;
this.wm_text_pos = wm_text_pos;
this.wm_text_color = wm_text_color;
this.wm_text_size = wm_text_size;
this.wm_text_font = wm_text_font;
}
public FontText(){}
}