JAVA工具類之多圖片合成與圖片新增文字
阿新 • • 發佈:2019-01-10
應公司需要,需要給每個客戶生成個性的微信圖片二維碼,涉及到背景圖片、微信帶參二維碼和微信頭像的合成,並將微信你暱稱新增在上面。
效果如下:
圖片實現程式碼,需依賴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(){}
}