java给图片加文字水印,同时解决windows下正常,linux下乱码问题

1.前言:

业务逻辑:低功耗相机拍的照片发到后台,图片上时间不太准确。
解决方案:低功耗模式下拍的照片发到后台时不带时间,由后台拿到图片后,在进行打上时间水印。
e.g:原本时间错误的图片:
在这里插入图片描述
e.g:后台处理后,加上水印后的图片
在这里插入图片描述

2.java给图片加上文字水印

我的业务逻辑就是拿到图片流,然后用ImageIo和Graphics2D进行加水印,最后再转换成流,存入minio中。

        byte[] imageByte = imageBuffer.toByteArray();
        ByteArrayInputStream bais = new ByteArrayInputStream(imageByte);
        //如果osd是false 关着的 给图片加上水印
        if (!basicPlateInfo.getOsdFlag()) {
            //将文件对象转化为图片对象
            Image srcImg = ImageIO.read(bais);
            //获取图片的宽
            int srcImgWidth = srcImg.getWidth(null);
            //获取图片的高
            int srcImgHeight = srcImg.getHeight(null);
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            // 加水印
            //创建画笔
            Graphics2D g = bufImg.createGraphics();
            //绘制原始图片
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            //-------------------------文字水印 start----------------------------
            //根据图片的背景设置水印颜色
            g.setColor(new Color(255, 255, 255, 255));
            //设置字体  画笔字体样式为微软雅黑,加粗,文字大小为60pt
            g.setFont(new Font("微软雅黑", Font.PLAIN, 50));
            //水印内容
            Date date = new Date();
            DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            String strDate = dateFormat.format(date);
            if (StringUtils.isBlank(plateColorName)) {
                plateColorName = "UNKOWN";
            }
            String plateStatus = null;
            if (parkingSpotStatus == 0) {
                plateStatus = "空";
            } else if (parkingSpotStatus == 1) {
                plateStatus = "驶入";
            } else if (parkingSpotStatus == 2) {
                plateStatus = "停稳";
            } else if (parkingSpotStatus == 3) {
                plateStatus = "驶出";
            } else if (parkingSpotStatus == 4) {
                plateStatus = "已离开";
            } else {
                plateStatus = "抓拍";
            }
            int x = 25;
            int y = 57;
            int x1 = 25;
            int y1 = 120;
            int x2 = 300;
            int y2 = 120;
            //画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
            g.drawString(strDate, x, y);
            g.drawString(plateColorName, x1, y1);
            g.drawString(plateStatus, x2, y2);
            g.dispose();
            //-------------------------文字水印 end----------------------------
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(bufImg, "jpg", byteArrayOutputStream);
            InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            minioClient.putObject(PutObjectArgs.builder().bucket("image").object(imageName).stream(inputStream, inputStream.available(), -1).contentType("image/jpeg").build());
            inputStream.close();
            byteArrayOutputStream.close();

引用的代码,附上原文链接

/**
 * 图片添加水印
 * @author qzz
 */
public class ImageUtils {

    public static void main(String[] args) throws IOException {
        // 读取原图片信息 得到文件(本地图片)
        File srcImgFile = new File("F:/image/1.png");
        //将文件对象转化为图片对象
        Image srcImg = ImageIO.read(srcImgFile);
        //获取图片的宽
        int srcImgWidth = srcImg.getWidth(null);
        //获取图片的高
        int srcImgHeight = srcImg.getHeight(null);
        System.out.println("图片的宽:"+srcImgWidth);
        System.out.println("图片的高:"+srcImgHeight);

        //创建一个URL对象,获取网络图片的地址信息(网络图片)
//        URL url = new URL("https://pngimg.com/distr/img/ukraine.png");
//        //将URL对象输入流转化为图片对象 (url.openStream()方法,获得一个输入流)
//        Image srcImg = ImageIO.read(url.openStream());
//        //获取图片的宽
//        int srcImgWidth = srcImg.getWidth(null);
//        //获取图片的高
//        int srcImgHeight = srcImg.getHeight(null);
//        System.out.println("图片的宽:"+srcImgWidth);
//        System.out.println("图片的高:"+srcImgHeight);



        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        // 加水印
        //创建画笔
        Graphics2D g = bufImg.createGraphics();
        //绘制原始图片
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        //-------------------------文字水印 start----------------------------
        //根据图片的背景设置水印颜色
        g.setColor(new Color(255,255,255,128));
        //设置字体  画笔字体样式为微软雅黑,加粗,文字大小为60pt
        g.setFont(new Font("微软雅黑", Font.BOLD, 60));
        //水印内容
        String waterMarkContent="图片来源:https://image.baidu.com/";
        //设置水印的坐标(为原图片中间位置)
        int x=(srcImgWidth - getWatermarkLength(waterMarkContent, g)) / 2;
        int y=srcImgHeight / 2;
        //画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
        g.drawString(waterMarkContent, x, y);
        g.dispose();
        //-------------------------文字水印 end----------------------------
        //待存储的地址
        String tarImgPath="F:/image/t.png";
        // 输出图片
        FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
        ImageIO.write(bufImg, "png", outImgStream);
        System.out.println("添加水印完成");
        outImgStream.flush();
        outImgStream.close();

    }
    
    /**
     * 获取水印文字的长度
     * @param waterMarkContent
     * @param g
     * @return
     */
    public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }
}
————————————————
版权声明:本文为CSDN博主「12程序猿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_26383975/article/details/125996277

3.解决乱码问题(windows下正常,但是放到linux服务器上汉字乱码)

linux上文字乱码的图片:
在这里插入图片描述
原因:linux系统中没有中文字,可以使用 fc-list :lang=zh 检查是否有:下图表示有
在这里插入图片描述

解决办法:

1.c盘,windows目录下,fonts目录下,搜索自己想要的字体,因为我项目中用的是微软雅黑,所以搜的是它。

在这里插入图片描述

2.在linux中/usr/share/fonts目录下创建chinese文件夹,然后使用sftp工具将windows中的文件上传到chinese目录下。

在这里插入图片描述

3. 来到chinese目录下执行命令:

chmod 755 *.ttc

4.然后reboot或者重启项目服务。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值