0101中文乱码-BufferedImage-图片处理

文章目录

1、问题描述

接手维护一个休闲赛事类项目,因为服务器到期,项目从云服务器迁移到本地服务器。

项目生成比赛,分为二人组、三人组等等的团体;比赛设置几个赛点,每个赛点扫描二维码,完成比赛后,由管理人员生成完赛证明和完赛证书(电子图片)。

在项目迁移完成后,发现生成的图片中表示队伍和人名的中文文字乱码了,如下图所示:

2 、电子证书生成

生成图片源代码如下所示:

java 复制代码
 public static boolean certImageTo2(String backgroundPath, String outPutPath, Map<String, Object> fontMap) throws IOException {
//        int width = 2404;//2021
        int width = 1309;//2022
//        int height = 1000;//2021
        int height = 992;//2022
        // 设置背景图片大小
        BufferedImage backgroundImage = resizeImage(width, height, ImageIO.read(new File(backgroundPath)));
        // 设置二维码图片大小
        Graphics2D g2d = backgroundImage.createGraphics();

        //消除文字锯齿
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        //消除画图锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        //队员
        String memberName = String.valueOf(fontMap.get("memberName"));
        int nameWidth = 315;
        int nameHeight = 574;
        int fontSize = 20;
        if (memberName != null) {
            if (memberName.length() == 2) {
                nameHeight = nameHeight + 10;
            }else if (memberName.length() == 4) {
                nameHeight = nameHeight - 12;
            }else if (memberName.length() == 5) {
                nameHeight = nameHeight - 16;
                fontSize = 16;
                nameWidth = nameWidth + 2;
            } else if (memberName.length() > 5) {//最多支持7个字
                nameHeight = nameHeight - 20;
                fontSize = 12;
                nameWidth = nameWidth + 4;
            }
        }
//        fontMap.put("memberName", "a");//temp test code
//        Font font = new Font("LiSu", Font.BOLD, fontSize);
        Font font = new Font("宋体", Font.BOLD, fontSize);
        g2d.setColor(new Color(0, 0, 0));
        g2d.setFont(font);
        shuPaiWenzi(nameWidth, nameHeight, 0, String.valueOf(fontMap.get("memberName")), g2d);

        //小时
//        font = new Font("LiSu", Font.PLAIN, 24);
        font = new Font("宋体", Font.PLAIN, 24);
        g2d.setColor(new Color(0, 0, 0));
        g2d.setFont(font);
        g2d.drawString(String.valueOf(fontMap.get("hour")), 288, 761);

        //分
//        font = new Font("LiSu", Font.PLAIN, 24);
        font = new Font("宋体", Font.PLAIN, 24);
        g2d.setColor(new Color(0, 0, 0));
        g2d.setFont(font);
        int x = 288;
        int minute = Integer.valueOf(String.valueOf(fontMap.get("minute")));
        Console.log("==========minute" + minute);
        if (minute >= 10) {
            x = x - 6;
        }
        g2d.drawString(String.valueOf(fontMap.get("minute")), x, 824);

        //秒
//        font = new Font("LiSu", Font.PLAIN, 24);
        font = new Font("宋体", Font.PLAIN, 24);
        g2d.setColor(new Color(0, 0, 0));
        g2d.setFont(font);
        x = 288;
        int second = Integer.valueOf(String.valueOf(fontMap.get("second")));
        Console.log("==========second" + second);
        if (second >= 10) {
            x = x - 6;
        }
        g2d.drawString(String.valueOf(fontMap.get("second")), x, 890);

        // 释放
        g2d.dispose();

        // 输出新的图片
        return ImageIO.write(backgroundImage, "jpg", new File(outPutPath));
    }
  • BufferedImage为内存图形对象,加载背景图重新设置宽高。
  • Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供、坐标转换、颜色管理以及文字布局等更精确的控制。
  • 这里我们通过Graphics2D在背景图对应位置设置字符串来生成精美的电子证书。
  • 字符串可以设置字体、颜色、大小等等。

3、中文乱码原因及修复

问题分析:

  • 首先我们直接迁移的war包,程序是没有动过的。
  • 图片正常生成,英文字符串也正常生成,只有中文乱码。
  • 这里我们猜测可能出现问题地方
    • 是不是数据库排序规则问题
    • 是不是和系统环境有关?(具体什么呢?)

本地运行代码:

  • 代码在本地测试正常的,排除数据库问题

上网搜索之后,确定一个方向和Linux没有安装中文字体是否有关?

因为是线上系统,不可能仅凭一个猜测就去搞测试,那我们就自己准备一个云服务器,来还原问题。

第一步:不按照中文字体,运行程序,结果中文乱码。

第二步:安装中文字体,参考下面链接1,因为程序中使用"宋体"和"隶书",我们直接把本地的这两种字体安装上,重新运行程序,结果正常。

  • 安装中文字体后,一定要重启程序,不然不生效。

最终确认是由于本地服务器未安装相应的中文字体导致的

4、思考

如何让我们的内容正好对应我们的背景图中预留位置呢?你适配了某个比赛的背景,我其他比赛需要做不同的背景图,长宽比例,位置可能变动?

结语

❓QQ:806797785

⭐️仓库地址:https://gitee.com/gaogzhen

⭐️仓库地址:https://github.com/gaogzhen

[1]centos7安装字体和中文字体[CP/OL].

相关推荐
NullPointerExpection7 天前
使用 Java 原生的 ImageIO、Graphics2D 实现图片任意坐标范围的裁剪( 解决图片宽高交换的问题 )
java·graphics2d·图片裁剪·bufferedimage·imageio
小陈努力学1123581322 天前
如何使用GPT画出带中文的图和表?-已解决GPT画图表出现乱码的问题
gpt·中文乱码
lingFei_y1 个月前
【axios get请求 中文乱码】
vue.js·中文乱码·axios·get
jupiter_8882 个月前
SecureCRT连接Linux时乱码问题
中文乱码·securecrt
J_bean5 个月前
怎么设置 idea terminal 窗口的编码格式
中文乱码·编码格式·idea·terminal 窗口
源代码•宸5 个月前
高效解决Visual Studio Code中文乱码问题
utf-8·经验分享·中文乱码·visual studio code·gbk
Z顺其自然6 个月前
Linux-vim显示乱码
linux·运维·中文乱码·vim·shell
青石路6 个月前
Windows NFS 真弱 → 中文乱码导致文件找不到
中文乱码·nfs·线上问题
try_learner7 个月前
Spring + Tomcat项目中nacos配置中文乱码问题解决
spring·nacos·中文乱码