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(){}
}
  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值