场景:将一个头像、二维码、文字信息添加到一张背景图片中,将这些信息合成一张图片。
代码已经测试验证。代码中图片自己随意找几张测试即可。
代码:
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(); } } }