Java 生成图片(图片合成二维码、文字)

package com.ssish.wxmall.common.data;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;

import org.apache.commons.lang3.StringUtils;

 
/**
 * Java 图片生成
 * 
 * @author houzhenghai
 * @date 2018年10月19日 下午4:59:35
 */
public class DrawingUtils {
 
   private static float jPEGcompression = 0.75f;// 图片清晰比率
   
   
   /**
    * 图片制作
    * @param backImage 背景图地址
    * @param srcImage  二维码地址
    * @param descImage //生成后的图片
    * @param descImageLeft
    * @param descImageTop
    */
   public static void makeImage(String backImage, String srcImage, String descImage,
         int descImageLeft,int descImageTop) {
       try {
           int offset = 0;
           BufferedImage backBufferedImage = ImageIO.read(new URL(backImage));
           BufferedImage srcBufferedImage = ImageIO.read(new URL(srcImage));
           // 输出图片宽度
           int width = backBufferedImage.getWidth() + offset;
           // 输出图片高度
           int height = backBufferedImage.getHeight() + offset;
           BufferedImage descBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
           Graphics2D graphics2d = (Graphics2D) descBufferedImage.getGraphics();
           graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
           // 往画布上添加图片,并设置边距
           graphics2d.drawImage(backBufferedImage, null, 0, 0);
           graphics2d.drawImage(srcBufferedImage, null, descImageLeft, descImageTop);
           graphics2d.dispose();
           // 输出新图片
           ImageIO.write(descBufferedImage, backImage.substring(backImage.lastIndexOf(".")+1, backImage.length()), new File(descImage));
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
   
   /**
    * @Description : 将二维码图片和文字生成到一张图片上
    * @Param : localFilePath 生成的新图片存放路径
    * @Param : originalImg 原图
    * @Param : qrCodeImg 二维码地址
    * @Param : shareDesc 图片文字
    * @return : java.lang.String
    * @Author : houzhenghai
    * @Date : 2018/8/15
    */
   public static ByteArrayOutputStream makeImage(String localFilePath,String originalImg, String qrCodeImg,int qrCodePaddingLeft,int qrCodePaddingTop,int qrCodeWidth,int qrCodeHeight,String shareDesc) throws Exception {
      /*
      // 加载原图图片
      BufferedImage imageLocal = ImageIO.read(new URL(originalImg));
      // 加载用户的二维码
      BufferedImage imageCode = ImageIO.read(new URL(qrCodeImg));
      // 以原图片为模板
      Graphics2D g = imageLocal.createGraphics();
      AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
      g.setComposite(ac);
      g.setBackground(Color.WHITE);
      // 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知)
      //g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null);
      g.drawImage(imageCode, qrCodePaddingLeft, imageLocal.getHeight() - qrCodePaddingTop, qrCodeWidth, qrCodeHeight, null);
      // 设置文本样式
      g.setFont(new Font("微软雅黑", Font.PLAIN, 40));
      g.setColor(Color.red);
      // 计算文字长度,计算居中的x点坐标
      //g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530);
 
      // 设置文本样式
      g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16));
      g.setColor(Color.WHITE);
      // 计算文字长度,计算居中的x点坐标
      String caewm = "长按二维码";
      g.drawString(caewm, 105, imageLocal.getHeight() - 10);
 
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      */
      // 加载原图图片
      BufferedImage imageLocal = null;
      if(StringUtils.isNotBlank(originalImg)&&originalImg.toLowerCase().indexOf("http")!=-1) {
         imageLocal = ImageIO.read(new URL(originalImg));
      }else {
         imageLocal = ImageIO.read(new File(originalImg));
      }
      // 加载用户的二维码
      BufferedImage imageCode = null;
      if(StringUtils.isNotBlank(qrCodeImg)&&qrCodeImg.toLowerCase().indexOf("http")!=-1) {
         imageCode = ImageIO.read(new URL(qrCodeImg));
      }else {
         imageCode = ImageIO.read(new File(qrCodeImg));
      }
      // 以原图片为模板
      Graphics2D g = imageLocal.createGraphics();
      AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
      g.setComposite(ac);
      g.setBackground(Color.WHITE);
      // 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知)
      //g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null);
      //g.drawImage(imageCode, 100, imageLocal.getHeight() - 50, 43, 43, null);

      //加载头像 http://image.ssish.com/uniFolder/476/userAvatar/0.png
      /*String headImg="http://image.ssish.com/uniFolder/476/userAvatar/0.png";
      BufferedImage headCode = null;
      if(StringUtils.isNotBlank(headImg)&&headImg.toLowerCase().indexOf("http")!=-1) {
         headCode = ImageIO.read(new URL(headImg));
      }else {
         headCode = ImageIO.read(new File(headImg));
      }
      g.drawImage(headCode, 100, imageLocal.getHeight() - 100, 100, 100, null);*/

      g.drawImage(imageCode, qrCodePaddingLeft, imageLocal.getHeight() - qrCodePaddingTop, qrCodeWidth, qrCodeHeight, null);
      // 设置文本样式
      g.setFont(new Font("微软雅黑", Font.PLAIN, 40));
      g.setColor(Color.red);
      // 计算文字长度,计算居中的x点坐标
      g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530);
 
      // 设置文本样式
      g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16));
      g.setColor(Color.WHITE);
      // 计算文字长度,计算居中的x点坐标
      /*
      String caewm = "长按二维码";
      g.drawString(caewm, 105, imageLocal.getHeight() - 10);
      */
      ByteArrayOutputStream out = new ByteArrayOutputStream();
            
      saveAsJPEG(imageLocal, out);
      
      
      //FileOutputStream fileOutputStream = new FileOutputStream( new File( "d:/1123.jpg" ) ) ;

      //out.writeTo(fileOutputStream) ;

        //fileOutputStream.flush();
      //out.close();
      //return urlImgDownInputStream(FileUtils.parse(out));
      
      FileOutputStream fileOutputStream = new FileOutputStream( new File(localFilePath) ) ;

      out.writeTo(fileOutputStream) ;

        fileOutputStream.flush();
      out.close();
      
      return out;
   }
   
 
   /**
    * @Description : 将二维码图片和文字生成到一张图片上
    * @Param : originalImg 原图
    * @Param : qrCodeImg 二维码地址
    * @Param : shareDesc 图片文字
    * @return : java.lang.String
    * @Author : houzhenghai
    * @Date : 2018/8/15
    */
   public static String generateImg(String originalImg, String qrCodeImg, String shareDesc) throws Exception {
      // 加载原图图片
      BufferedImage imageLocal = ImageIO.read(new URL(originalImg));
      // 加载用户的二维码
      BufferedImage imageCode = ImageIO.read(new URL(qrCodeImg));
      // 以原图片为模板
      Graphics2D g = imageLocal.createGraphics();
      AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
      g.setComposite(ac);
      g.setBackground(Color.WHITE);
      // 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知)
      //g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null);
      //g.drawImage(imageCode, 100, imageLocal.getHeight() - 50, 43, 43, null);
      g.drawImage(imageCode, 760, imageLocal.getHeight() - 340, 300, 300, null);
      // 设置文本样式
      g.setFont(new Font("微软雅黑", Font.PLAIN, 40));
      g.setColor(Color.red);
      // 计算文字长度,计算居中的x点坐标
      /*
      g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530);
      */
      // 设置文本样式
      g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16));
      g.setColor(Color.WHITE);
      // 计算文字长度,计算居中的x点坐标
      /*
      String caewm = "长按二维码";
      g.drawString(caewm, 105, imageLocal.getHeight() - 10);
      */
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      
      
        
        
      
      saveAsJPEG(imageLocal, out);
      
      FileOutputStream fileOutputStream = new FileOutputStream( new File( "d:/1123.jpg" ) ) ;

      out.writeTo(fileOutputStream) ;

        fileOutputStream.flush();
      out.close();
      //return urlImgDownInputStream(FileUtils.parse(out));
      return null;
   }
   
   
   
   public static void mergeImage(String backImage, String srcImage, String descImage) {
       try {
           int offset = 0;
           BufferedImage backBufferedImage = ImageIO.read(new URL(backImage));
           BufferedImage srcBufferedImage = ImageIO.read(new URL(srcImage));
           // 输出图片宽度
           int width = backBufferedImage.getWidth() + offset;
           // 输出图片高度
           int height = backBufferedImage.getHeight() + offset;
           BufferedImage descBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
           Graphics2D graphics2d = (Graphics2D) descBufferedImage.getGraphics();
           graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
           // 往画布上添加图片,并设置边距
           graphics2d.drawImage(backBufferedImage, null, 0, 0);
           graphics2d.drawImage(srcBufferedImage, null, 175, 175);
           graphics2d.dispose();
           // 输出新图片
           ImageIO.write(descBufferedImage, "png", new File(descImage));
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
 
   /**
    * 以JPEG编码保存图片
    * 
    * @param image_to_save
    *            要处理的图像图片
    * @param fos
    *            文件输出流
    * @throws IOException
    */
   private static void saveAsJPEG(BufferedImage imageToSave, ByteArrayOutputStream fos) throws IOException {
      ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpg").next();
      ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
      imageWriter.setOutput(ios);
      if (jPEGcompression >= 0 && jPEGcompression <= 1f) {
         // new Compression
         JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
         jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
         jpegParams.setCompressionQuality(jPEGcompression);
 
      }
      // new Write and clean up
      ImageIO.setUseCache(false);
      imageWriter.write(new IIOImage(imageToSave, null, null));
      ios.close();
      imageWriter.dispose();
   }
 
   /**
    * 图片流远程上传
    * 
    * @author houzhenghai
    * @date 2018年10月19日 下午5:07:24
    * @param inStream
    * @param imgType
    * @return
    * @throws Exception
    */
   /*
   private static String urlImgDownInputStream(InputStream inStream) throws Exception {
      String md5 = MD5Utils.MD5(TimeUtils.getTimestamp().toString());
      HttpClient httpclient = new DefaultHttpClient();
      try {
         HttpPost post = new HttpPost(IMG_UPLOAD_PATH);// 文件服务器上传图片地址
         MultipartEntity mpEntity = new MultipartEntity();
         ContentBody contb = new InputStreamBody(inStream, md5 + ".png");
         mpEntity.addPart("Filedata", contb);
         post.setEntity(mpEntity);
         HttpResponse httpResponse = httpclient.execute(post);
         HttpEntity entity = httpResponse.getEntity();
         String jsonStr = EntityUtils.toString(entity);
         JSONObject ob = JSONObject.fromObject(jsonStr);
         if (!ob.isEmpty() && ob.containsKey("pic_id")) {
            return ob.getString("pic_id");
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         httpclient.getConnectionManager().shutdown();
      }
      return null;
   }
   */
 
   /**
    * test
    * 
    * @param args
    * @throws
    */
   /*
   public static void main(String[] args) {
      long starttime = System.currentTimeMillis();
      System.out.println("开始:" + starttime);
      try {
         String originalImg = "http://image.run4wd.com/newBee/invitationposter/821806.jpg";
         String qrCodeImg = "http://image.run4wd.com/newBee/invitationposter/qrcode/612278_qrcode.jpg";
         String shareDesc = "";
         String img = generateImg(originalImg, qrCodeImg, shareDesc);
         System.out.println("生成完毕,url=" + img);
      } catch (Exception e) {
         e.printStackTrace();
      }
      System.out.println("结束:" + (System.currentTimeMillis() - starttime) / 1000);
   }
   */
   
   public static void main(String[] args) {
      long starttime = System.currentTimeMillis();
      System.out.println("开始:" + starttime);
      /*
      //两张图片合成一张
      try {
         String originalImg = "http://image.ssish.com/newBee/poster/invitation/765029.jpg";
         String qrCodeImg = "http://image.ssish.com/uniFolder/476/poster/1586411727926.jpg";
         String shareDesc = "d:/33.png";
         makeImage(originalImg, qrCodeImg, shareDesc,760,1389);
         //System.out.println("生成完毕,url=" + img);
      } catch (Exception e) {
         e.printStackTrace();
      }
      */



      //两张图片合成一张并加文字
      String[] posterInvitationPositionParamArr = "280,280,760,345,280,280".split(",");
      //String localFilePath="/datavg/temp/newimg.png";//生成的新图片放在临时目录下
      String localFilePath="d:/test.jpg";//生成的新图片放在临时目录下
      String originalImg = "http://image.ssish.com/newBee/poster/invitation/823941.jpg";
      String qrCodeImg = "http://image.ssish.com/uniFolder/476/poster/1586411727926.jpg";
      try {
         ByteArrayOutputStream os=DrawingUtils.makeImage(localFilePath,originalImg, qrCodeImg, Integer.valueOf(posterInvitationPositionParamArr[2]), Integer.valueOf(posterInvitationPositionParamArr[3]), Integer.valueOf(posterInvitationPositionParamArr[4]), Integer.valueOf(posterInvitationPositionParamArr[5]), "张三,欢迎你!");
      } catch (Exception e) {
         e.printStackTrace();
      }

      //把生成的新图片上传到服务器,并删除临时目录下的文件
      /*String fileName=localFilePath.substring(localFilePath.lastIndexOf("/")+1,localFilePath.length());
      ossService.upload(new File(localFilePath),"poster/invitation/"+fileName);
      FileUtils.deleteFile(localFilePath);*/
      System.out.println("结束:" + (System.currentTimeMillis() - starttime) / 1000);
   }
 
}

 合成后的新图片

 

Java 生成图片(图片合成二维码、文字)