利用java代码将多张图片合成一张图片

 

利用java代码将多张图片合成一张图片

 效果展示:

 

 工具类

  1 import cn.hutool.core.collection.CollUtil;
  2 import cn.hutool.core.convert.Convert;
  3 import lombok.extern.slf4j.Slf4j;
  4 import org.apache.http.util.Asserts;
  5 
  6 import javax.imageio.ImageIO;
  7 import java.awt.*;
  8 import java.awt.image.BufferedImage;
  9 import java.io.File;
 10 import java.io.FileInputStream;
 11 import java.io.IOException;
 12 import java.util.Arrays;
 13 import java.util.List;
 14 import java.util.UUID;
 15 
 16 
 17 /**
 18  * 把两张图片合并一张
 19  */
 20 @Slf4j
 21 public class ImgDealUtils {
 22 
 23 
 24     /**
 25      * 图片大小重构
 26      */
 27     public static BufferedImage resizeImage(int x, int y, BufferedImage bfi) {
 28         BufferedImage bufferedImage = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
 29         bufferedImage.getGraphics().drawImage(bfi.getScaledInstance(x, y, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
 30         return bufferedImage;
 31     }
 32 
 33     /**
 34      * 合并图片
 35      * 待合并的图片必须满足这样的前提,
 36      * 以第一个图片未基准水平、垂直扩展
 37      * 如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
 38      *
 39      * @param type     合并方向 1-水平方向;2-垂直方向
 40      * @param destPath 合并后的图片路径
 41      * @param imgList  待合并的图片路径
 42      */
 43     public static void mergeImage(Integer type, String destPath, List<String> imgList) {
 44         if (CollUtil.isEmpty(imgList)) {
 45             return;
 46         }
 47         BufferedImage first = null;
 48         try {
 49             first = ImageIO.read(new FileInputStream(imgList.get(0)));
 50         } catch (IOException e) {
 51             log.error("合并图片失败", e);
 52         }
 53         // 图像压缩  保证每张图片大小一致
 54         int w1 = first.getWidth();
 55         int h1 = first.getHeight();
 56         mergeImageByWidthAndHeight(type, destPath, imgList, w1, h1);
 57     }
 58 
 59     public static void mergeImageByWidthAndHeight(Integer type, String destPath,
 60                                                   List<String> imgList,
 61                                                   int width, int height) {
 62 
 63         if (CollUtil.isEmpty(imgList)) {
 64             return;
 65         }
 66         try {
 67             // 生成新图片,第一张图片左上角坐标为(0,0)
 68             BufferedImage destImage;
 69             Graphics2D graphics2D;
 70             if (type == 1) {
 71                 //水平方向合并
 72                 destImage = new BufferedImage(width * imgList.size(), height, BufferedImage.TYPE_INT_RGB);
 73                 graphics2D = destImage.createGraphics();
 74                 for (int i = 0; i < imgList.size(); i++) {
 75                     BufferedImage image = ImageIO.read(new FileInputStream(imgList.get(i)));
 76                     BufferedImage imgTem = resizeImage(width, height, image);
 77                     graphics2D.drawImage(imgTem, width * i, 0, imgTem.getWidth(), height, null);
 78                 }
 79             } else if (type == 2) {
 80                 //垂直方向合并
 81                 destImage = new BufferedImage(width, height * imgList.size(), BufferedImage.TYPE_INT_RGB);
 82                 graphics2D = destImage.createGraphics();
 83                 for (int i = 0; i < imgList.size(); i++) {
 84                     BufferedImage image = ImageIO.read(new FileInputStream(imgList.get(i)));
 85                     BufferedImage imgTem = resizeImage(width, height, image);
 86                     graphics2D.drawImage(imgTem, 0, height * i, width, imgTem.getHeight(), null);
 87                 }
 88             } else {
 89                 return;
 90             }
 91             graphics2D.dispose();
 92             log.info("生成新图片path:{}", destPath);
 93             ImageIO.write(destImage, "jpg", new File(destPath));
 94         } catch (IOException e) {
 95             log.error("生成新图片失败", e);
 96         }
 97     }
 98 
 99     /**
100      * 合并图片(支持文字图片一起合并)
101      * 待合并的图片必须满足这样的前提,
102      * 以第一个图片未基准水平、垂直扩展
103      * 如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
104      *
105      * @param type     合并方向 1-水平方向;2-垂直方向
106      * @param destPath 合并后的图片路径
107      * @param imgList  待合并的图片路径
108      * @param fontSize 字体大小
109      */
110     public static void mergeImageIncludeText(Integer type, String destPath, List<String> imgList, Integer fontSize) {
111         if (CollUtil.isEmpty(imgList)) {
112             return;
113         }
114         BufferedImage first;
115         int height = 100;
116         int width = 100;
117         try {
118             final String s = imgList.stream().filter(img -> img.endsWith(".jpg")).findFirst().orElse(null);
119             if (s != null) {
120                 first = ImageIO.read(new FileInputStream(imgList.get(0)));
121                 width = first.getWidth();
122                 height = first.getHeight();
123             }
124         } catch (IOException e) {
125             log.error("合并图片失败", e);
126         }
127         fontSize = Convert.toInt(fontSize, 60);
128         // 图像压缩  保证每张图片大小一致
129         mergeImageByWidthAndHeightIncludeText(type, destPath, imgList, width, height, fontSize);
130     }
131 
132 
133     public static void mergeImageByWidthAndHeightIncludeText(Integer type, String destPath,
134                                                              List<String> imgList,
135                                                              int width, int height, int fontSize) {
136 
137         if (CollUtil.isEmpty(imgList)) {
138             return;
139         }
140         try {
141             Asserts.check(fontSize <= width, "字体过大");
142             // 生成新图片,第一张图片左上角坐标为(0,0)
143             BufferedImage destImage;
144             Graphics2D graphics2D;
145             if (type == 1) {
146                 //水平方向合并
147                 destImage = new BufferedImage(width * imgList.size(), height, BufferedImage.TYPE_INT_RGB);
148                 graphics2D = destImage.createGraphics();
149                 for (int i = 0; i < imgList.size(); i++) {
150                     final String path = imgList.get(i);
151                     if (path.endsWith(".jpg")) {
152                         BufferedImage image = ImageIO.read(new FileInputStream(imgList.get(i)));
153                         BufferedImage imgTem = resizeImage(width, height, image);
154                         graphics2D.drawImage(imgTem, width * i, 0, imgTem.getWidth(), height, null);
155                     } else {
156                         //字体大小随字数变化
157                         final int length = path.length();
158                         int fontSizeNew = fontSize / length;
159                         graphics2D.setFont(new Font("微软雅黑", Font.PLAIN, fontSizeNew));
160                         for (int j = 0; j < length; j++) {
161                             char c = path.charAt(j);
162                             // 文字竖排    x轴大概位于中间,y轴从上排
163                             graphics2D.drawString(Convert.toStr(c), i * width + width / 2 - fontSizeNew / 2, (height / length * j + fontSizeNew));
164                         }
165                     }
166                 }
167             } else if (type == 2) {
168                 //垂直方向合并
169                 destImage = new BufferedImage(width, height * imgList.size(), BufferedImage.TYPE_INT_RGB);
170                 graphics2D = destImage.createGraphics();
171                 for (int i = 0; i < imgList.size(); i++) {
172                     final String path = imgList.get(i);
173                     if (path.endsWith(".jpg")) {
174                         BufferedImage image = ImageIO.read(new FileInputStream(imgList.get(i)));
175                         BufferedImage imgTem = resizeImage(width, height, image);
176                         graphics2D.drawImage(imgTem, 0, height * i, width, imgTem.getHeight(), null);
177                     } else {
178                         //字体大小随字数变化
179                         final int length = path.length();
180                         int fontSizeNew = fontSize / length;
181                         graphics2D.setFont(new Font("微软雅黑", Font.PLAIN, fontSizeNew));
182                         for (int j = 0; j < length; j++) {
183                             char c = path.charAt(j);
184                             // 文字横排 y轴大概位于中间,x轴从上排
185                             graphics2D.drawString(Convert.toStr(c), (width / length * j + width / length / 2 - fontSizeNew / 2), i * height + height / 2 + fontSizeNew / 2);
186                         }
187                     }
188                 }
189             } else {
190                 return;
191             }
192             graphics2D.dispose();
193             log.info("生成新图片path:{}", destPath);
194             ImageIO.write(destImage, "jpg", new File(destPath));
195         } catch (IOException e) {
196             log.error("生成新图片失败", e);
197         }
198 
199     }
200 
201     public static void main(String[] args) {
202 
203         String pic1 = "D:\\tem\\baidu.jpg";
204         String pic2 = "D:\\tem\\baidu2.jpg";
205 
206         //水平方向合并
207         String destImg = "D:\\tem" + File.separator + UUID.randomUUID() + ".jpg";
208         log.info("水平方向合并path:{}", destImg);
209         mergeImage(1, destImg, Arrays.asList(pic1, "张三", pic2));
210         mergeImageIncludeText(1, destImg, Arrays.asList(pic1, "张三", "李四", pic2), null);
211         //垂直方向合并
212         String destImg2 = "D:\\tem" + File.separator + UUID.randomUUID() + ".jpg";
213         log.info("垂直方向合并:{}", destImg2);
214         mergeImage(2, destImg2, Arrays.asList(pic1, "张三", pic2));
215         mergeImageIncludeText(2, destImg2, Arrays.asList(pic1, "张三", "李四", pic2), null);
216     }
217 }
ImgDealUtils

 

 

参考:https://blog.csdn.net/weixin_48029654/article/details/127043664

https://blog.csdn.net/jiang_wang01/article/details/116525621

 

posted on 2024-02-26 17:04  腾逸  阅读(486)  评论(0编辑  收藏  举报