问题描述
使用 Graphics2D 画图的时候出现乱码情况,本地测试是没问题,放在linux服务器就出现乱码
DEMO代码
File file = new File("/home/war/test.png");
BufferedImage bi = new BufferedImage(400, 200, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D) bi.getGraphics();
g2.setBackground(Color.WHITE);
g2.clearRect(0, 0, 400, 200);
g2.setColor(Color.BLACK);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.drawString("为什么没有(ꐚꌒꑿꆺ)(ꐚꌒꑿꆺ)这名字特殊不?@¥¥¥ 为什么没有(ꐚꌒꑿꆺ)(ꐚꌒꑿꆺ)这名字特 ", 0, 10);
g2.dispose();
ImageIO.write(bi, "PNG", file);
linux 上面运行结果
问题排查
源码
首先Graphics2D 继承了 Graphics 类,可以看到该类使用的是模板方法模式
接着点击去
再点
这里判断是否设置字体,为空则为默认字体
网上冲浪了一下,发现原来JVM创建Font的时候会使用FontManagerFactory获取FontManager,而不同的系统使用的FontManager是不同的!Mac用的是CFontManager,而Linux用的是X11FontManager!
Java 运行时环境支持的 Java 平台所定义的五种字体系列:Serif、SansSerif、Monospaced、Dialog 和 DialogInput。这些逻辑字体不是实际的字体库。此外,由 Java 运行时环境将逻辑字体名称映射到物理字体。映射关系与实现和通常语言环境相关,因此它们提供的外观和规格各不相同。通常,为了覆盖庞大的字符范围,每种逻辑字体名称都映射到几种物理字体。
rt.jar
解决方法
原因:Linux环境加载字体问题
解决:
一、更改代码,指定字体
File file = new File("/home/war/test.png");
Font font = new Font("Serif", Font.PLAIN, 10);//指定字体
BufferedImage bi = new BufferedImage(400, 200, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D) bi.getGraphics();
g2.setBackground(Color.WHITE);
g2.clearRect(0, 0, 400, 200);
g2.setFont(font);
g2.setColor(Color.BLACK);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.drawString("为什么没有(ꐚꌒꑿꆺ)(ꐚꌒꑿꆺ)这名字特殊不?@¥¥¥ 为什么没有(ꐚꌒꑿꆺ)(ꐚꌒꑿꆺ)这名字特 ", 0, 10);
g2.dispose();
ImageIO.write(bi, "PNG", file);
二、Linux安装字体
C:\Windows\Fonts 这个目录下的文件可以全部打包上传,按照以下方式照样是可以使用的
Linux 命令
cd /usr/share/fonts #进入到该目录
mkdir myfonts #创建文件
cd myfonts #进入到该目录
#建立字体索引信息,更新字体缓存
mkfontscale
mkfontdir
fc-cache
三、柳暗花开
重启应用,再次生成图片