图片上叠加文字

在一个原有图片上叠加上指定的文字

编写一个工具类实现文字叠加的功能,叫ImageUttils

import cn.hutool.core.img.Img;
import cn.hutool.core.io.resource.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
//import sun.misc.BASE64Encoder;
import org.apache.commons.codec.binary.Base64;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;

/**
 * @ClassName ImageUtils
 * @Description 图片合成工具类
 * @Version
 **/
@Component
@Slf4j
public class ImageUtils {

    @Value("${image.fontSize}")
    private int fontSize;

    @Value("${image.backgroundColor}")
    private String backgroundColor;

    @Value("${image.fontColor}")
    private String fontColor;

    @Value("${image.compression}")
    private double compression;

    @Value("${text.line.height}")
    private int textLineHeight;

    @Value("${image.compress.size}")
    private Double imageCompressSize;

    public byte[] addTextToImage(String imageUrl, String text){
//        logger.info("修改base64");
        log.info("进入ImageUtils图片合成方法");
        long t1 = System.currentTimeMillis();
        //获取图片
        byte[] bytes = new byte[0];
        ByteArrayOutputStream baos  = null;
        try {
            Image image = ImageIO.read(new URL(imageUrl));
            int width = (int)(image.getWidth(null) * compression);
            int height = (int)(image.getHeight(null) * compression);
            log.debug("原图的大小为:width = {}, height = {}", width, height);
            int size = (int)(fontSize * compression);
            int n = width/size;
            String[] split = null;
            bytes = null;
            try {
                text= getStringByEnter(n, text);
//                split = StringUtils.split(text, "\\r?\\n");
                //更换成一下方式,上面的方法获取的split = null
                split = text.split("\n");
            } catch (Exception e) {
                log.error("imageUrl={},text={},getStringByEnter error , e = {}", imageUrl, text, e);
            }
            int heightPlus = 0;
            if (split== null || split.length==0){
                heightPlus = textLineHeight;
            } else {
                heightPlus = split.length * textLineHeight;
            }
            log.debug("heightPlus = {}", heightPlus);
            BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 =  bi.createGraphics();
            g2.drawImage(image, 0, 0, width, height - heightPlus, null);
            g2.setColor(colorMapping(fontColor));
            g2.setFont(new Font("宋体",Font.BOLD, size));
            //g2.drawString(text, 0, height - 2 * size);
            for(int i = 0 ; i < split.length; i++){
                String line = split[i];
                g2.drawString(line, 0, height - size*(split.length - i));
            }
            g2.dispose();
            baos = new ByteArrayOutputStream();
            //图片格式要保证和源图格式相同,否则图片大小差别会很大
            ImageIO.write(bi, "jpg", baos);
            bytes = baos.toByteArray();

            //压缩图片
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            InputStream sbs = new ByteArrayInputStream(bytes);
            Img.from(sbs).setQuality(imageCompressSize).write(out);
            return out.toByteArray();

        } catch (Exception e) {
            log.error("imageUrl={}, text={}, addTextToImage error = {}",imageUrl, text, e);
        } finally {
            try {
                baos.close();
            } catch (IOException e) {
                log.error("imageUrl={}, text={}, io close error , e = {}", imageUrl,text, e);
            }
        }
        long t2 = System.currentTimeMillis();
        log.info("imageUrl={}, text={}, addTextToImage cost = {}ms", imageUrl,text, t2 -t1);
        return bytes;
    }

    private static String getClassPath() {
        String classPath = null;
        URL url = ImageUtils.class.getResource("/");
        if(null != url){
            classPath = url.toString().replaceFirst("file:/", "/");
        }
        return classPath;
    }

    /**
     * 自动换行
     * @param string
     * @return
     */
    public String getStringByEnter(int length, String string) throws Exception {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < string.length(); i++)
        {
            /*if (string.substring(0, i).getBytes("GBK").length > length)
            {
                return string.substring(0, i - 1) + "\n" +
                    getStringByEnter(length, string.substring(i - 1));
            }*/
            sb.append(string.charAt(i));
            if((i+1)%length == 0){
                sb.append("\n");
            }
        }
        return sb.toString();
    }

    public String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
//        return new BASE64Encoder().encode(buffer);
        return Base64.encodeBase64String(buffer);
    }

    private Color colorMapping(String color){
        Color color1 = Color.BLACK;
        switch (color) {
            case "red":
                color1 =  Color.RED;
                break;
            case "white":
                color1 = Color.WHITE;
                break;
            case "gray":
                color1 = Color.GRAY;
                break;
            case "blue":
                color1 = Color.BLUE;
                break;
            default:
                color1 = Color.BLACK;
                break;
        }
        return color1;
    }
}

其中入参在配置文件中,如下

#------图片页面字体设置-------
image.backgroundColor=black
image.fontColor=red
image.fontSize=20
image.compression=1.0
text.line.height=33
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值