ImageBuilder

目标

用 Java 绘制分享图,需要将文字、用户头像、二维码等元素合成到背景图上。

外部依赖

Maven 依赖:



    com.google.zxing
    core
    (the current version)
 

源代码

import com.google.zxing.BarcodeFormat;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Objects;

/**
 * 

* 图像合成工具类 *

* Created by scott on 2018-11-13. */ public class ImageBuilder { private Graphics2D graphics; private BufferedImage bgImage; /** *
     *     BufferedImage bgImage;
     *     // 从网络加载
     *     bgImage = ImageIO.read(url);
     *     // 从文件中加载
     *     bgImage = ImageIO.read(file);
     * 
* * @param bgImage 背景图 */ public ImageBuilder(BufferedImage bgImage) { Objects.requireNonNull(bgImage); this.bgImage = bgImage; graphics = this.bgImage.createGraphics(); } public ImageBuilder withText(Font font, Color color, int x, int y, String text) { Objects.requireNonNull(font, "font 不能为 null"); Objects.requireNonNull(color, "color 不能为 null"); graphics.setFont(font); graphics.setColor(color); graphics.drawString(text, x, y); return this; } /** * 在底图上画圆形头像 */ public ImageBuilder withCircularAvatar(BufferedImage avatar, int x, int y, int diameter) { try { Ellipse2D.Double shape = new Ellipse2D.Double(x, y, diameter, diameter); graphics.setClip(shape); graphics.drawImage(avatar.getScaledInstance(diameter, diameter, Image.SCALE_SMOOTH), x, y, null); } catch (Exception e) { e.printStackTrace(); } return this; } /** * 在底图上画二维码 * * @param x 二维码中心坐标点 * @param y 二维码中心坐标点 */ public ImageBuilder withQRCode(String contents, int x, int y, int width) { try { QRCodeWriter writer = new QRCodeWriter(); // 生成二维码数据点 BitMatrix matrix = writer.encode(contents, BarcodeFormat.QR_CODE, width, width); int matrixWidth = matrix.getWidth(); // 计算二维码的原点(留2个像素作为边框) int p = getMatrixOriginPoint(matrix, matrixWidth) - 2; int aw = matrixWidth / 2 - p; // 填充二维码背景色 graphics.setColor(Color.WHITE); graphics.fillRect(x - aw, y - aw, aw * 2, aw * 2); // 填充二维码 graphics.setColor(Color.BLACK); for (int i = 0; i < matrixWidth; i++) { for (int j = 0; j < matrixWidth; j++) { if (matrix.get(i, j)) { graphics.fillRect(x - aw + i - p, y - aw + j - p, 1, 1); } } } } catch (Exception e) { e.printStackTrace(); } return this; } /** * 获取二维码原点 */ private int getMatrixOriginPoint(BitMatrix matrix, int matrixWidth) { for (int i = 0; i < matrixWidth; i++) { for (int j = 0; j < matrixWidth; j++) { if (matrix.get(i, j)) { return i; } } } return 0; } /** * 在底图上画一个已有的图片 * * @param width 在底图上要画的图片宽度 * @param height 在底图上要画的图片高度 */ public ImageBuilder withImage(BufferedImage material, int x, int y, int width, int height) { graphics.drawImage(material, x, y, width, height, null); return this; } /** * 在底图上画一个已有的图片 *

* 使用小图片默认 *

*/ public ImageBuilder withImage(BufferedImage material, int x, int y) throws IOException { return withImage(material, x, y, material.getWidth(), material.getHeight()); } /** * 生成图片 */ public BufferedImage build() { graphics.dispose(); return bgImage; } /** * 生成本地图片 * * @param formatName 生成的文件格式名称(例如:jpg、png),要与背景图的格式保持一致 * @param output 生成的图片 */ public boolean writeTo(String formatName, File output) throws IOException { return ImageIO.write(bgImage, formatName, output); } }

示例

public class ImageBuilderTest {

    public static void main(String[] args) {
        String inputPath = "C:\\Users\\scott\\Pictures\\01.png";
        String outputPath = "C:\\Users\\scott\\Pictures\\01_out.png";
        try {
            BufferedImage bgImg = ImageIO.read(new File(inputPath));

            ImageBuilder builder = new ImageBuilder(bgImg);

            String text = "我是共产主义接班人";
            builder.withText(new Font("黑体", Font.BOLD, 20), Color.black, 40, 40, text);
            builder.build();

            ImageIO.write(bgImg, "png", new File(outputPath));

            System.out.println("done");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

你可能感兴趣的:(ImageBuilder)