1. 程式人生 > >JAVA工具類之多圖片合成與圖片新增文字

JAVA工具類之多圖片合成與圖片新增文字

應公司需要,需要給每個客戶生成個性的微信圖片二維碼,涉及到背景圖片、微信帶參二維碼和微信頭像的合成,並將微信你暱稱新增在上面。
效果如下:
這裡寫圖片描述
圖片實現程式碼,需依賴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(){}
}