java Graphics2D 获取当前系统实际支持特殊字符和中文的字体

获取系统所有字体

/**
 * 显示当前系统环境支持的字体
 */
@Test
void getAvailableFontFamilyNames() {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fontNames = ge.getAvailableFontFamilyNames();
    for (String fontName : fontNames) {
        System.out.println(fontName);
    }
}

注意,该方法只能获取到当前系统有哪些字体,并不代表着 Graphics2D 也支持这些字体。所以才需要下文去筛选出 Graphics2D 真正支持的字体出来。

初步筛选出支持中文的字体

/**
 * 用系统所有字体生成一个图片,用于初步筛选出支持中文的字体
 */
@Test
void allFonts() {
    int fontSize = 20;
    // 获取当前系统所有字体
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fontNames = ge.getAvailableFontFamilyNames();
    String str = "东临碣石,以观沧海。水何澹澹,山岛竦峙。树木丛生,百草丰茂。秋风萧瑟,洪波涌起。日月之行,若出其中;星汉灿烂,若出其里。幸甚至哉,歌以咏志。";
    int height = 0;
    int width = 0;
    // 根据字体获取需要生成的图片的宽和高
    for (String fontName : fontNames) {
        Font font = new Font(fontName, Font.PLAIN, fontSize);
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        height += metrics.getHeight();
        int tmpWidth = metrics.stringWidth(fontName + " : " + str);
        if (tmpWidth > width) {
            width = tmpWidth;
        }
    }
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    Graphics2D g2d = null;
    try {
        //创建画笔
        g2d = image.createGraphics();
        //设置背景颜色为白色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
        //设置画笔颜色为黑色
        g2d.setColor(Color.BLACK);
        RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        // 开启文字抗锯齿
        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHints(hints);
        int startY = 0;
        for (String fontName : fontNames) {
            Font font = new Font(fontName, Font.PLAIN, fontSize);
            System.out.println(fontName);
            g2d.setFont(font);
            g2d.drawString(fontName + " : " + str, 0, startY);
            // 下一行文字的左上角纵坐标
            FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
            startY += metrics.getHeight();
        }
        String savePath = "\\temp\\all_fonts.png";
        ImageIO.write(image, "PNG", new File(savePath));
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (g2d != null) {
            g2d.dispose();
        }
    }
}

得到所有字体生成的图片

所有字体生成的图片
根据图片结果,可以初步筛选出支持中文的字体有:
Arial Unicode MS、Dialog、DialogInput、Microsoft JhengHei、Microsoft JhengHei Light、Microsoft JhengHei UI、Microsoft JhengHei UI Light、Microsoft YaHei UI、Microsoft YaHei UI Light、MS Gothic、MS PGothic、MS UI Gothic、SansSerif、Serif、仿宋、华文中宋、华文仿宋、华文宋体、华文彩云、华文新魏、华文楷体、华文琥珀、华文细黑、华文行楷、华文隶书、宋体、幼圆、微软雅黑、微软雅黑 Light、新宋体、方正姚体、方正舒体、楷体、等线、等线 Light、隶书、黑体

进一步筛选支持中文和特殊字符的字体

/**
 * 用初步支持中文的字体绘制长文本,进一步校验中文的支持
 */
@Test
void fonts() {
    int fontSize = 24;
    String[] fontNames = {
            "Arial Unicode MS",
            "Dialog",
            "DialogInput",
            "Microsoft JhengHei",
            "Microsoft JhengHei Light",
            "Microsoft JhengHei UI",
            "Microsoft JhengHei UI Light",
            "Microsoft YaHei UI",
            "Microsoft YaHei UI Light",
            "MS Gothic",
            "MS PGothic",
            "MS UI Gothic",
            "SansSerif",
            "Serif",
            "仿宋",
            "华文中宋",
            "华文仿宋",
            "华文宋体",
            "华文彩云",
            "华文新魏",
            "华文楷体",
            "华文琥珀",
            "华文细黑",
            "华文行楷",
            "华文隶书",
            "宋体",
            "幼圆",
            "微软雅黑",
            "微软雅黑 Light",
            "新宋体",
            "方正姚体",
            "方正舒体",
            "楷体",
            "等线",
            "等线 Light",
            "隶书",
            "黑体"
    };
    int height = 2000;
    int width = 600;
    // 需要绘制的文字(可自行添加其他字符或者中文去校验)
    String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz:;<=>?@[\\]^_`{|}~¡i¢£¥§¤©ªa«°o0±²2³3µ¶·.¹1º0»¼½¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÍÏÑÒÓÔÕÖOEØÙÚÛÜYyYßàáâãäåæçèéêëìíîïñòóôõöoeøùúûüÿ天地玄黄,宇宙洪荒。日月盈昃,辰宿列张。寒来暑往,秋收冬藏。闰余成岁,律吕调阳。云腾致雨,露结为霜。金生丽水,玉出昆冈。剑号巨阙,珠称夜光。果珍李柰,菜重芥姜。海咸河淡,鳞潜羽翔。龙师火帝,鸟官人皇。始制文字,乃服衣裳。推位让国,有虞陶唐。吊民伐罪,周发殷汤。坐朝问道,垂拱平章。爱育黎首,臣伏戎羌。遐迩一体,率宾归王。鸣凤在竹,白驹食场。化被草木,赖及万方。盖此身发,四大五常。恭惟鞠养,岂敢毁伤。女慕贞洁,男效才良。知过必改,得能莫忘。罔谈彼短,靡恃己长。信使可覆,器欲难量。墨悲丝染,诗赞羔羊。景行维贤,克念作圣。德建名立,形端表正。空谷传声,虚堂习听。祸因恶积,福缘善庆。尺璧非宝,寸阴是竞。资父事君,曰严与敬。孝当竭力,忠则尽命。临深履薄,夙兴温凊。似兰斯馨,如松之盛。川流不息,渊澄取映。容止若思,言辞安定。笃初诚美,慎终宜令。荣业所基,籍甚无竟。学优登仕,摄职从政。存以甘棠,去而益咏。乐殊贵贱,礼别尊卑。上和下睦,夫唱妇随。外受傅训,入奉母仪。诸姑伯叔,犹子比儿。孔怀兄弟,同气连枝。交友投分,切磨箴规。仁慈隐恻,造次弗离。节义廉退,颠沛匪亏。性静情逸,心动神疲。守真志满,逐物意移。坚持雅操,好爵自縻。都邑华夏,东西二京。背邙面洛,浮渭据泾。宫殿盘郁,楼观飞惊。图写禽兽,画彩仙灵。丙舍旁启,甲帐对楹。肆筵设席,鼓瑟吹笙。升阶纳陛,弁转疑星。右通广内,左达承明。既集坟典,亦聚群英。杜稿钟隶,漆书壁经。府罗将相,路侠槐卿。户封八县,家给千兵。高冠陪辇,驱毂振缨。世禄侈富,车驾肥轻。策功茂实,勒碑刻铭。盘溪伊尹,佐时阿衡。奄宅曲阜,微旦孰营。桓公匡合,济弱扶倾。绮回汉惠,说感武丁。俊义密勿,多士实宁。晋楚更霸,赵魏困横。假途灭虢,践土会盟。何遵约法,韩弊烦刑。起翦颇牧,用军最精。宣威沙漠,驰誉丹青。九州禹迹,百郡秦并。岳宗泰岱,禅主云亭。雁门紫塞,鸡田赤城。昆池碣石,钜野洞庭。旷远绵邈,岩岫杳冥。治本于农,务兹稼穑。俶载南亩,我艺黍稷。税熟贡新,劝赏黜陟。孟轲敦素,史鱼秉直。庶几中庸,劳谦谨敕。聆音察理,鉴貌辨色。贻厥嘉猷,勉其祗植。省躬讥诫,宠增抗极。殆辱近耻,林皋幸即。两疏见机,解组谁逼。索居闲处,沉默寂寥。求古寻论,散虑逍遥。欣奏累遣,戚谢欢招。渠荷的历,园莽抽条。枇杷晚翠,梧桐蚤凋。陈根委翳,落叶飘摇。游鹍独运,凌摩绛霄。耽读玩市,寓目囊箱。易輶攸畏,属耳垣墙。具膳餐饭,适口充肠。饱饫烹宰,饥厌糟糠。亲戚故旧,老少异粮。妾御绩纺,侍巾帷房。纨扇圆洁,银烛炜煌。昼眠夕寐,蓝笋象床。弦歌酒宴,接杯举觞。矫手顿足,悦豫且康。嫡后嗣续,祭祀烝尝。稽颡再拜,悚惧恐惶。笺牒简要,顾答审详。骸垢想浴,执热愿凉。驴骡犊特,骇跃超骧。诛斩贼盗,捕获叛亡。布射僚丸,嵇琴阮啸。恬笔伦纸,钧巧任钓。释纷利俗,并皆佳妙。毛施淑姿,工颦妍笑。年矢每催,曦晖朗曜。璇玑悬斡,晦魄环照。指薪修祜,永绥吉劭。矩步引领,俯仰廊庙。束带矜庄,徘徊瞻眺。孤陋寡闻,愚蒙等诮。谓语助者,焉哉乎也。";
    Graphics2D g2d = null;
    try {
        for (String fontName : fontNames) {
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
            //创建画笔
            g2d = image.createGraphics();
            //设置背景颜色为白色
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
            //设置画笔颜色为黑色
            g2d.setColor(Color.BLACK);
            RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            // 开启文字抗锯齿
            hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2d.setRenderingHints(hints);

            Font font = new Font(fontName, Font.PLAIN, fontSize);
            g2d.setFont(font);
            FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
            // 生成换行文本
            char[] chars = str.toCharArray();
            int tmpWidth = 0;
            List<String> lines = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < chars.length; i++) {
                char c = chars[i];
                tmpWidth += metrics.charWidth(c);
                if (tmpWidth > image.getWidth()) {
                    // 换行
                    lines.add(sb.toString());
                    sb = new StringBuilder();
                    tmpWidth = 0;
                    i--;
                } else {
                    sb.append(c);
                }
            }
            if (sb.length() > 0) {
                lines.add(sb.toString());
            }

            // 绘制每行文字
            for (int i = 0; i < lines.size(); i++) {
                String line = lines.get(i);
                g2d.drawString(line, 0, metrics.getAscent() + metrics.getHeight() * i);
            }

            String savePath = "\\temp\\text_test2\\" + fontName + ".png";
            ImageIO.write(image, "PNG", new File(savePath));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (g2d != null) {
            g2d.dispose();
        }
    }
}

例如字体 MS Gothic 得到的图片中,可以看到虽然特殊字符支持,但是不少中文是不支持的:

MS Gothic
例如华文彩云字体得到的图片中,部分特殊字符是不支持的:

华文彩云

最终根据各个字体生成的图片,得出当前系统支持特殊字符和大部分中文的字体有:

字体名称中文友好度特殊字符友好度
Arial Unicode MS
Dialog
DialogInput
Microsoft JhengHei
Microsoft JhengHei Light
Microsoft JhengHei UI
Microsoft JhengHei UI Light
Microsoft YaHei UI
Microsoft YaHei UI Light
MS Gothic部分
MS PGothic部分
MS UI Gothic部分
SansSerif
Serif
仿宋部分
华文中宋
华文仿宋
华文宋体
华文彩云部分
华文新魏部分
华文楷体
华文琥珀部分
华文细黑
华文行楷部分
华文隶书部分
宋体
幼圆部分
微软雅黑
微软雅黑 Light
新宋体
方正姚体
方正舒体
楷体部分
等线
等线 Light
隶书部分
黑体部分

注:可自行在str中添加自己需要校验的特殊字符和中文,这里只校验到:《千字文》的中文、大小写英文字母、以及特殊字符:;<=>?@[]^_`{|}~¡i¢£¥§¤©ªa«°o0±²2³3µ¶·.¹1º0»¼½¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÍÏÑÒÓÔÕÖOEØÙÚÛÜYyYßàáâãäåæçèéêëìíîïñòóôõöoeøùúûüÿ

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值