利用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 }
参考:https://blog.csdn.net/weixin_48029654/article/details/127043664
https://blog.csdn.net/jiang_wang01/article/details/116525621