需求描述:
生成二维码时,需要在二维码的头部、底部根据需求添加文字描述。
初次实现:
Font topFont = new Font("宋体", Font.BOLD, 24);
Font bottomFont = new Font("宋体", Font.BOLD, 16);
问题:
windows上正常显示,但是发布到服务器上后:所有中文乱码解决方式:
1、首先想到的是编码问题,但是查看代码,没有与编码相关的问题
2、然后上网查看了下资料,基本上是说Linux中缺少中文字体,然后都是各种Linux及docker中安装中文字体,由于项目是居于阿里云k8s自动部署,passe了此方法
3、最后采用了一劳永逸的方式,将字体文件放入sources文件中,采用java.awt.Font.createFont()自定义字体方式进行处理
1、windows中文件字体存放位置:C:\Windows\Fonts
2、后续内容借鉴的是此篇博客:java.awt.Font.createFont 画图的时候字体不显示问题
新方式的新问题:
初次尝试:
Font topFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
topFont.deriveFont(Font.BOLD, 24);
Font bottomFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
bottomFont = font.deriveFont(Font.BOLD, 24);
生成结果:文字直接成点去了,设置字体大小依然无效
参照上面的博客,进行字体注册 依然无效,猜测是否是注册时机不对,创建字体后紧接着就注册,依然无效。
突然看到Font.createFont方法的注释:
译文:通过复制这个Font对象并应用新的样式和大小来创建一个新的Font对象。
重点:复制、创建一个新的对象
真正原因:deriveFont()不会修改原对象,而是返回一个新的对象
解决方式:
Font font = Font.createFont(Font.TRUETYPE_FONT, inputStream);
Font topFont = font.deriveFont(Font.BOLD, 24);
Font bottomFont = font.deriveFont(Font.BOLD, 16);
完美解决问题,正常显示字体了
代码简化: 尝试删除注册字体,一切正常
结论:
1、windwos中正常,但是发布到Linux或docker上中文乱码,是因为运行环境没有找到对应的字体
2、字体异常是由于deriveFont()方法不会改变原字体,而是重新生成了一个Font对象,需要使用方法返回的实例
花絮:
在初次尝试的时候,其实是出现了 java.awt.FontFormatException: bad pfa font 异常,是因为Font.createFont();参数导致的:
Font.createFont(Font.BOLD, inputStream);
Font.createFont(Font.TYPE1_FONT, inputStream);
以上两种方式均会报上面的异常,尝试过pom中忽略ttf、ttc的过滤再编译的(此处不再展示相关文章)配置,依然抛出此异常,
最后使用Font.createFont(Font.TRUETYPE_FONT, inputStream)解决异常。
写在结尾:
申明一下:
本博客不是针对上面博主文章,本来也在挣扎是否需要引用博客,毕竟确实最终结果以原博文有一定冲突,但是,
首先基于确实是参考了别人的东西,得写明出处及参考的地方;
其次也是感谢博主的分享;
然后毕竟使用场景肯定是有差异,实现有差异也是情理之中;
最后,也希望读者发现错误给予指出。