Java Swing渲染小像素字体出现拉伸变形问题与修复方案
JPanel渲染5x5极小像素字体无规律缩放问题
问题背景
个人项目以文本作为核心图形元素,需要在JPanel上渲染单字符尺寸为5x5像素的极小像素字体。调试阶段渲染大量点位与#字符时就已出现显示bug,初期影响范围小被忽略,近期优化系统时发现该问题已经严重影响显示效果,且未检索到公开的有效解决方案。
问题表现
5x5像素的字符出现近乎无规律的缩放,显示效果极差:#字符组成的线条不规整,渲染出的点位大小不一致。
预期效果
字符排列线条规整,渲染的所有点位大小均匀一致。
已尝试方案
- 通过
RenderingHints反复开关抗锯齿,无任何效果 - 所用像素字体通过BitFontMaker2工具生成,设置5px字间距后导出为TTF格式;尝试先在5x5像素尺寸的
BufferedImage上完成绘制,再将BufferedImage放大2倍提升可见度,问题未解决 - 此前与朋友合作的其他项目中也出现过同款问题:朋友的设备运行无该异常,本人设备始终存在该bug
相关实现代码
字体注册代码
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream("FontName.ttf"); font1= Font.createFont(Font.TRUETYPE_FONT, stream).deriveFont(5f); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); ge.registerFont(font1);
字符绘制调用代码(所有变量取值均验证正确)
g.drawString(s.substring(i,i+1),x*FONT_WIDTH+i*FONT_WIDTH,y*FONT_HEIGHT+FONT_HEIGHT);
渲染参数设置代码(已关闭抗锯齿,设置最近邻插值)
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
修复进展
该问题核心诱因为高DPI屏幕下Java2D默认开启的全局UI缩放,在程序最启动阶段(所有Swing组件初始化前)添加配置System.setProperty("sun.java2d.uiScale", "1");禁用Java2D自动缩放后,核心缩放问题已得到修复,仅存在少量残留bug,整体异常程度已大幅降低。
残留问题可从两个方向进一步排查:
- 确保所有绘制传入的x、y坐标均为整数值,避免Swing对亚像素坐标自动做对齐渲染导致的像素偏移
- 额外关闭两项字体渲染相关配置:将
KEY_TEXT_ANTIALIASING设为VALUE_TEXT_ANTIALIAS_OFF,将KEY_FRACTIONALMETRICS设为VALUE_FRACTIONALMETRICS_OFF,彻底禁用亚像素级字体位置微调
内容的提问来源于stack exchange,提问作者Leon Lavoie
相关产品推荐
相关产品推荐

