首页 > 编程语言 > java 实现图片合成,并添加文字
2020
12-16

java 实现图片合成,并添加文字

最近公司一个需要,需要把商品的优惠卷分享链接,生成一个二维码然后和商品主图合成一张,并且在新合成的主图增加商品信息的描述,好了直接看合成后图片的样式

下面我就直接贴代码,首先是Contorller层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
   * 淘宝二维码,商品主图,合成一张图
   *
   * @param pictUrl
   * @param request
   * @param response
   * @throws IOException
   */
  @RequestMapping("/getTaoBaoqQRCode")
  public void getTaoBaoqQRCode(TaoBaoQRCode taoBaoQRCode, HttpServletRequest request,
      HttpServletResponse response) throws IOException {
    ServletOutputStream os = null;
    InputStream buffin = null;
    try {
      // 二维码
      String couponUlr = "https:" + taoBaoQRCode.getCouponShareUrl();// 高额卷分享链接
      byte[] imgByte = QrCodeUtil.createQrCode2Bytes(250, 250, couponUlr);
      buffin = new ByteArrayInputStream(imgByte);
      BufferedImage couponImage = ImageIO.read(buffin);
      // 商品主图
      String imageUrl = "https:" + taoBaoQRCode.getPictUrl();
      URL url = new URL(imageUrl);
      BufferedImage picImage = ImageIO.read(url);
      BufferedImage modifyImage =
          imageHandleUtil.mergeImage(picImage, couponImage, taoBaoQRCode.getTitle(),
              taoBaoQRCode.getReservePrice(), taoBaoQRCode.getZkFinalPrice());
      response.setContentType("image/jpg");
      os = response.getOutputStream();
      ImageIO.write(modifyImage, "jpg", os);
      os.flush();
    } catch (Exception e) {
      LOGGER.error("getTaoBaoqQRCode error");
      e.printStackTrace();
    } finally {
      buffin.close();
      os.close();
    }
  }

二维码QrCodeUtil 生成帮助类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class QrCodeUtil {
  private static final int DAFAULT_WIDTH = 360;
  private static final int DAFAULT_HEIGHT = 360;
 
  private static final Logger LOGGER = LoggerFactory.getLogger(QrCodeUtil.class);
 
  public static String createQrCode(String text) {
    return createQrCode(DAFAULT_WIDTH, DAFAULT_HEIGHT, text);
  }
 
  public static String createQrCode(int widht, int height, String text) {
    HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
    try {
      byte[] bytes = createQrCode2Bytes(widht, height, text);
      String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
      return UpYunClient.upload(fileName, bytes);
    } catch (Exception e) {
      LOGGER.error("create qrcode error", e);
    }
    return null;
  }
 
 
  public static byte[] createQrCode2Bytes(String text) {
    return createQrCode2Bytes(DAFAULT_WIDTH, DAFAULT_HEIGHT, text);
  }
 
  public static byte[] createQrCode2Bytes(int widht, int height, String text) {
    HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
    try {
      BitMatrix bitMatrix =
          new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, widht, height,
              hints);
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
      ImageIO.write(image, "png", out);
      return out.toByteArray();
    } catch (Exception e) {
      LOGGER.error("create qrcode error", e);
    }
    return null;
  }
 
  /**
   * 生成条形码并已字节码形式返回,生成的图片格式为png
   *
   * @param contents
   * @param width
   * @param height
   * @return
   */
  public static byte[] createBarcode2Byte(String contents, int width, int height) {
    int codeWidth = 3 + // start guard
        (7 * 6) + // left bars
        5 + // middle guard
        (7 * 6) + // right bars
        3; // end guard
    codeWidth = Math.max(codeWidth, width);
    try {
      BitMatrix bitMatrix =
          new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, codeWidth,
              height, null);
      BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      ImageIO.write(image, "png", out);
      return out.toByteArray();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}

二维码生成我这里用的是谷歌的看下面maven pom.xml 文件

1
2
3
4
5
6
7
8
9
10
11
<!-- 条形码、二维码生成 -->
    <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>core</artifactId>
      <version>2.2</version>
    </dependency>
    <dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>javase</artifactId>
      <version>2.2</version>
    </dependency>

合成图片方法如何

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
package com.qft.campuscircle.common.util;
 
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import org.springframework.stereotype.Component;
 
@Component
public class ImageHandleUtil {
  private Font font = null;
  private Graphics2D g = null;
 
  /**
   * 导入本地图片到缓冲区
   *
   * @param imgName
   * @return
   */
  public BufferedImage loadImageLocal(String imgName) {
    try {
      return ImageIO.read(new File(imgName));
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }
 
  /**
   * 导入网络图片到缓冲区
   *
   * @param imgName
   * @return
   */
  public BufferedImage loadImageUrl(String imgName) {
    try {
      URL url = new URL(imgName);
      return ImageIO.read(url);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }
 
  /**
   * 生成新图片到本地
   *
   * @param newImage
   * @param img
   */
  public void writeImageLocal(String newImage, BufferedImage img) {
    if (newImage != null && img != null) {
      try {
        // 目录不存在则创建
        String dirUrl = newImage.substring(0, newImage.lastIndexOf(File.separator));
        File dir = new File(dirUrl);
        if (!dir.exists()) {
          dir.mkdirs();
        }
        File outputfile = new File(newImage);
        ImageIO.write(img, "png", outputfile);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
 
  /**
   * 设定文字的字体等
   *
   * @param fontStyle
   * @param fontSize
   */
  public void setFont(String name, int style, int fontSize) {
    this.font = new Font(name, style, fontSize);
  }
 
  /**
   * 修改图片,返回修改后的图片缓冲区(只输出一行文本),图片居中显示
   *
   * @param img
   * @param content
   * @param y
   * @param color
   * @return
   */
  public BufferedImage modifyImage(BufferedImage img, Object content, int y, Color color) {
    try {
      g = img.createGraphics();
      g.setBackground(Color.WHITE);
      g.setColor(color);// 设置字体颜色
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿
      if (this.font != null)
        g.setFont(this.font);
      int width = img.getWidth();// 图片宽度
      if (content != null) {
        String str = content.toString();
        int strWidth = g.getFontMetrics().stringWidth(str);// 字体宽度
        g.drawString(str, (width - strWidth) / 2, y);
      }
      g.dispose();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return img;
  }
 
  public BufferedImage modifyImage(BufferedImage img, Object content, int x, int y, Color color) {
    try {
      g = img.createGraphics();
      g.setBackground(Color.WHITE);
      g.setColor(color);// 设置字体颜色
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿
      if (this.font != null)
        g.setFont(this.font);
      if (content != null) {
        String str = content.toString();
        g.drawString(str, x, y);
      }
      g.dispose();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return img;
  }
 
  /**
   * 将一张图片画在另一张图片上
   *
   * @param addImage 被添加的图片
   * @param sourceImg 源图
   * @param x
   * @param y
   * @param width
   * @param height
   * @return
   */
  public BufferedImage modifyImagetogeter(BufferedImage addImage, BufferedImage sourceImg, int x,
      int y) {
    int width = addImage.getWidth();
    int height = addImage.getHeight();
    try {
      g = sourceImg.createGraphics();
      g.drawImage(addImage, x, y, width, height, null);
      g.dispose();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return sourceImg;
  }
  /**
   *
   * @param img1
   * @param img2
   * @param title 标题
   * @param reservePrice 现价
   * @param zkFinalPrice 折扣价
   * @return BufferedImage
   * @throws IOException
   */
  public BufferedImage mergeImage(BufferedImage img1, BufferedImage img2,String title,String reservePrice,String zkFinalPrice)
      throws IOException {
    Font font = new Font("微软雅黑", Font.BOLD, 20);
    int w1 = img1.getWidth();
    int h1 = img1.getHeight();
    int w2 = img2.getWidth();
    int h2 = img2.getHeight();
    BufferedImage newImage = new BufferedImage(w1, h2 + h1 + h2/2, BufferedImage.TYPE_INT_RGB);// 新的图
    Graphics2D graphics = (Graphics2D) newImage.getGraphics();
    graphics.setBackground(Color.WHITE);
    graphics.fillRect(0, 0, newImage.getWidth(), newImage.getHeight());
    graphics.drawImage(img1, 0, 0, null);
    graphics.drawImage(img2, (newImage.getWidth()) / 2 - (w2 / 2), newImage.getHeight() - h2,
        null);
    graphics.setFont(font);
    graphics.setColor(Color.BLACK);
    int width = graphics.getFontMetrics(font).stringWidth(title);
    int startY = h1 + 30;
    if (width > newImage.getWidth()) {
      char[] array = title.toCharArray();
      StringBuilder sb = new StringBuilder(array[0]);
      for (char c : array) {
        sb.append(c);
        int newWidth = graphics.getFontMetrics(font).stringWidth(sb.toString());
        if ((newWidth + 19) >= newImage.getWidth()) {// 准备换行
          graphics.drawString(sb.toString(), 0, startY);
          startY += 30;
          sb.delete(0, sb.length());
        }
      }
      graphics.drawString(sb.toString(), 0, startY);
    } else {
      graphics.drawString(title, 0, startY);
    }
    graphics.drawString("现价¥"+reservePrice, 0, startY + 30);
    startY += 30;
    graphics.drawString("卷后价¥"+zkFinalPrice, 0, startY + 30);
    return newImage;
  }
}

两个帮助类里面有很多方法没用到,大家只要看几个关键的方法就可以了,TaoBaoQRCode 对象里面的属性我就没列出来了,大家自己根据自己的需求而定

以上就是java 实现图片合成,并添加文字的详细内容,更多关于Java 图片合成的资料请关注自学编程网其它相关文章!

编程技巧