Image合并添加文字内容

场景:将一个头像、二维码、文字信息添加到一张背景图片中,将这些信息合成一张图片。

代码已经测试验证。代码中图片自己随意找几张测试即可。

代码:

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * @Author : guoyanan
 * @Title : 图片处理工具类
 * @Time : 2019/03/25 16:59
 * @Document : 提供在元素图片中,添加文字和添加图片的功能,图片支持椭圆形显示
 */
public class ImageUtils {
         // 初始化当前类
         private static ImageUtils imageUtils = new ImageUtils();
         // Image 工具类
         private  Graphics2D graphics2D = null;
        // 原始图片
         private BufferedImage bufferedImage = null;

    /**
     * 懒汉单例模式
     * @return
     */
    public static ImageUtils getInstance(){
           return imageUtils;
        }

    /**
     *  基础图片初始化,传入作为背景图片的的路径
     * @param imageUrl
     * @return
     * @throws IOException
     */
    public Graphics2D getGraphics2DBaseImage(String imageUrl) throws IOException {
        InputStream inputStream = new FileInputStream(imageUrl);
         bufferedImage = ImageIO.read(inputStream);
        if (inputStream != null) {
            inputStream.close();
            graphics2D = bufferedImage.createGraphics();

        }
        return graphics2D;
    }


    /**
     * 在图片中添加文字内容
     * @param content
     * @param color
     * @param font
     * @param x
     * @param y
     */
    public void  setString(String content, Color color, Font font, Integer x, Integer y){
        // 图片的默认设置
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 设置字体的颜色
        graphics2D.setColor(color);
        // 设置字体、字体大小、字体效果(倾斜,底线等)
        graphics2D.setFont(font);
        // 设置字体显示的内容和位置
        graphics2D.drawString(content, x, y);
    }

    /**
     * 处理要合并的图片,支持图片椭圆行处理
     * @param imageUrl
     * @param x
     * @param y
     * @param isEllipse
     * @throws IOException
     */
    public void setImageLocalShape(String imageUrl, Integer x, Integer y, boolean isEllipse)throws IOException{
        // 需要处理的图片
        InputStream inputStreamIcon = new FileInputStream(imageUrl);
        BufferedImage bufferedImageIcon = ImageIO.read(inputStreamIcon);
        if (inputStreamIcon != null) {
            inputStreamIcon.close();
        }
        // 判断是否作椭圆处理
        if(isEllipse) {
            /**
             * 在处理合并图片形状时,一定要重新获取下原始图片的Graphics2D类,否则,会出现
             * 多个图片情况下只能有一个图片合并成功,其他图片不显示的情况
             * 原因: 实例引用覆盖导致的。调用clip()方法会将原先的图片覆盖导致只处理当前图片的情况
              */
            Graphics2D graphics2DEll = bufferedImage.createGraphics();
            // 将图片处理为圆形
            Ellipse2D.Double shape = new Ellipse2D.Double(x, y, bufferedImageIcon.getWidth(), bufferedImageIcon.getHeight());
            graphics2DEll.clip(shape);
            graphics2DEll.drawImage(bufferedImageIcon, x, y, null);
        }else {
            graphics2D.drawImage(bufferedImageIcon, x, y, null);
        }

    }

    /**
     * 处理图片的位置和大小图形
     * @param imageUrl
     * @param x
     * @param y
     * @param width
     * @param height
     * @param isEllipse
     * @throws IOException
     */
    public void setImageLocalShapeSize(String imageUrl, Integer x, Integer y, Integer width, Integer height, boolean isEllipse)throws IOException{
        // 需要处理的图片
        InputStream inputStreamIcon = new FileInputStream(imageUrl);
        BufferedImage bufferedImageIcon = ImageIO.read(inputStreamIcon);
        if (inputStreamIcon != null) {
            inputStreamIcon.close();
        }
        // 判断是否作椭圆处理
        if(isEllipse) {
            /**
             * 在处理合并图片形状时,一定要重新获取下原始图片的Graphics2D类,否则,会出现
             * 多个图片情况下只能有一个图片合并成功,其他图片不显示的情况
             * 原因: 实例引用覆盖导致的。调用clip()方法会将原先的图片覆盖导致只处理当前图片的情况
             */
            Graphics2D graphics2DEll = bufferedImage.createGraphics();
            // 将图片处理为圆形
            Ellipse2D.Double shape = new Ellipse2D.Double(x, y, bufferedImageIcon.getWidth(), bufferedImageIcon.getHeight());
            graphics2DEll.clip(shape);
            graphics2DEll.drawImage(bufferedImageIcon, x, y, width, height, null);
        }else {
            graphics2D.drawImage(bufferedImageIcon, x, y, width, height, null);
        }


    }

    /**
     *  目标图片生成
     * @param imageUrl
     * @throws IOException
     */
    public void  targetImage(String imageUrl) throws IOException{
        // 初始化目标图片的路径
        OutputStream outputStream = new FileOutputStream(imageUrl);
        // 生成图片
        JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder(outputStream);
        // 将生成图片中添加的信息处理
        enc.encode(bufferedImage);
         // 释放合并图片占用的资源信息
        graphics2D.dispose();
    }

    public static  void main(String[] args){
        // 获取工具类实例
        ImageUtils imageUtils = ImageUtils.getInstance();
        try {
            // 设置背景图片
            imageUtils.getGraphics2DBaseImage("F:\tmp\yqxr_back.jpg");
            // 设置字体
            Color color=new Color(152,99,59);
            Font font = new Font("微软雅黑", Font.PLAIN, 20);// 添加字体的属性设置
            String str = "我对你的爱是真的。";
            
            imageUtils.setString(str,color,font,175,790);

            // 设置头像
            imageUtils.setImageLocalShapeSize("F:\tmp\pic.png",310, 635,120,120,true);
            // 二维码
            imageUtils.setImageLocalShapeSize("F:\tmp\timg.jpg",230, 810,305,307,false);
            // 图标
            imageUtils.setImageLocalShape("F:\tmp\icon.png",340, 920,false);
            // 生成图片
            imageUtils.targetImage("F:\tmp\target100.jpg");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
原文地址:https://www.cnblogs.com/gynbk/p/10600337.html