Java文字描边效果实现

news2024/12/28 5:16:11

效果:

FontUtil工具类的完整代码如下:

其中实现描边效果的函数为:generateAdaptiveStrokeFontImage()

package com.ncarzone.data.contentcenter.biz.img.util;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import sun.font.FontDesignMetrics;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

/**
 * 字体处理工具类
 */
public class FontUtil {
    public static String TTF_ZHIZUN = "ZHIZUN"; // 至尊体
    public static String TTF_BIAOTIHEI = "BIAOTIHEI"; // 标题黑

   
    /**
     * 自适应方式的文字转描边的艺术字图片
     * @param text 文本内容
     * @param fontTTFName 字体名称
     * @param fontWeight 字体大小
     * @param fontColor 字体颜色
     * @param isItalic 是否倾斜
     * @return 字体图片信息
     */
    public static BufferedImage generateAdaptiveStrokeFontImage(String text, String fontTTFName, float fontWeight,
                                                                Color fontColor, boolean isItalic){
        //字体加载以及设置
        Font font = loadFont(fontTTFName, fontWeight, isItalic);

        int textWidth = new Double(getWordFontWidth(font, text) * 1.06).intValue();  // 考虑倾斜的影响,稍微增加长度
        int textHeight = getFontHeight(font);

        BufferedImage bi = new BufferedImage(textWidth, textHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = (Graphics2D) bi.getGraphics();

        // 增加下面代码使得背景透明
        bi = g2d.getDeviceConfiguration().createCompatibleImage(textWidth, textHeight, Transparency.TRANSLUCENT);
        g2d.dispose();

        g2d = (Graphics2D) bi.getGraphics();
        //消除锯齿
        ImageUtil.antialiasing(g2d);

        FontRenderContext frc = g2d.getFontRenderContext();
        TextLayout tl = new TextLayout(text, font, frc);
        Shape sha = tl.getOutline(AffineTransform.getTranslateInstance(0,fontWeight));

        g2d.setStroke(new BasicStroke((float)(fontWeight * 0.1)));
        g2d.setColor(Color.BLACK);
        g2d.draw(sha);
        g2d.setColor(fontColor);
        g2d.fill(sha);
        g2d.dispose();

        return bi;
    }

    /**
     * 加载字体
     * @param fontTTFName 字体名称
     * @param fontWeight 字体大小
     * @param isItalic 字体是否倾斜
     * @return
     */
    public static Font loadFont(String fontTTFName, float fontWeight, boolean isItalic){
        //字体加载以及设置
        Font font = null;
        try {
            Resource fontResource = new ClassPathResource("fonts/" + fontTTFName + ".TTF");
            InputStream inputStream = fontResource.getInputStream();
            Font f = Font.createFont(Font.TRUETYPE_FONT, inputStream);
            if( isItalic ){
                font = f.deriveFont(Font.PLAIN, fontWeight).deriveFont(AffineTransform.getShearInstance(-0.18, 0));
            }else{
                font = f.deriveFont(Font.PLAIN, fontWeight);
            }

        }catch (IOException | FontFormatException e){
            e.printStackTrace();
        }

        return font;
    }

    /**
     * 计算文字占用的字体宽度总和
     * @param font   字体
     * @param content 文字
     * @return
     */
    public static int getWordFontWidth(Font font, String content){
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int width = 0;
        for( int i = 0; i < content.length(); i++ ){
            width += metrics.charWidth(content.charAt(i));
        }
        return width;
    }

    /**
     * 获取字体的高度
     * @param font
     * @return
     */
    public static int getFontHeight(Font font){
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
        int height = metrics.getHeight();
        return height;
    }
}

消除锯齿函数的代码如下:

// 消除锯齿
    public static void antialiasing(Graphics2D g2d){
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    }

测试代码如下:

BufferedImage bi = FontUtil.generateAdaptiveStrokeFontImage("中秋节快乐", "BIAOTIHEI", 300, Color.WHITE, true);
ImageUtil.storeImg2LocalStorage(bi, "font", 3);

其中保存测试图片的代码为:

// 保存图片到本地
    public static void storeImg2LocalStorage(BufferedImage bi, String name, int i){
        try{
            ImageIO.write(bi, "png", new File("D:\\temp\\image\\output\\" + name + i + ".png"));
        }catch (IOException e){
            e.printStackTrace();
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1020719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

爱思唯尔——利用AI来改善医疗决策和科研

爱思唯尔(Elsevier)是一家全球性的多媒体出版公司&#xff0c;为教育、专业科学和医疗社区提供20,000多种产品&#xff0c;其中包括《柳叶刀》和《细胞》等领先的研究出版物。 该公司正处于数字化转型的第一阶段&#xff0c;将公司140年中发表在报告和期刊上的大量数据数字化。…

小米华为,化干戈为玉帛!

近日来&#xff0c;手机圈又掀起了各大厂家推出新品的高潮。首先是华为Mate60的推出&#xff0c;其自研的麒麟9000S芯片瞬间点燃了国内手机市场&#xff0c;得到了国内甚至国外业界人士的认可和好评。 而近日网上盛传的小米创始人雷军的“愿意加入华为技术生态圈”的邀请&…

CRM客户管理软件对出海企业的帮助与好处

2023我们走出了疫情的阴霾&#xff0c;经济下行压力大&#xff0c;面对内需的不足&#xff0c;国内企业纷纷选择出海&#xff0c;拓展海外业务增加企业营收。企业出海不是一件易事&#xff0c;有了CRM系统可以让公司事半功倍&#xff0c;下面就来说一说CRM客户管理软件能为出海…

亚马逊应该怎么快速提升排名,获取review?

跨境电商做久了&#xff0c;卖家都会陷入一个困境&#xff0c;到底是该坚持慢慢做好&#xff0c;还是要测评&#xff1f; 现在跨境电商平台人人都在刷&#xff0c;不刷单想成功真的很难&#xff0c;不是没可能&#xff0c;但是选品要非常好&#xff0c;而且你的listing也要做好…

网络编程 day1

1->x.mind网络编程基础 2->简述字节序的概念&#xff0c;并用共用体&#xff08;联合体&#xff09;的方式计算本机的字节序 1.字节序是指不同类型的CPU主机&#xff0c;内存存储多字节整数序列的方式 2.小端字节序&#xff1a;低序字节存储在低地址上 3.大端字节序&a…

ROS 入门

目录 简介 ROS诞生背景 ROS的设计目标 ROS与ROS2 安装ROS 1.配置ubuntu的软件和更新 2.设置安装源 3.设置key 4.安装 5.配置环境变量 安装可能出现的问题 安装构建依赖 卸载 ROS架构 1.设计者 2.维护者 3. 立足系统架构: ROS 可以划分为三层 ROS通信机制 话…

007-第一代软件需求整理

第一代软件需求整理 文章目录 第一代软件需求整理项目介绍需求来源需求来源1&#xff1a;竞品软件分析需求来源2&#xff1a;医生&#xff08;市场&#xff09;需求来源3&#xff1a;项目组内部需求来源4&#xff1a;软件组内部需求来源5&#xff1a;软件开发成员需求来源6&…

Java精品项目源码第61期垃圾分类科普平台(代号V061)

Java精品项目源码第61期垃圾分类科普平台(代号V061) 大家好&#xff0c;小辰今天给大家介绍一个垃圾分类科普平台&#xff0c;演示视频公众号&#xff08;小辰哥的Java&#xff09;对号查询观看即可 文章目录 Java精品项目源码第61期垃圾分类科普平台(代号V061)难度指数&…

LeetCode: 4. Median of Two Sorted Arrays

LeetCode - The Worlds Leading Online Programming Learning Platform 题目大意 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。 请你找出这两个有序数组的中位数&#xff0c;并且要求算法的时间复杂度为 O(log(m n))。 你可以假设 nums1 和 nums2 不会同时为空。 …

平衡二叉树删除结点后的调整操作

1.回顾插入操作 插入新结点后&#xff0c;要保持二叉排序树的特性不变&#xff08;左<中<右)若插入新结点导致不平衡&#xff0c;则需要调整平衡。 2.删除操作 删除结点后&#xff0c;要保持二叉排序树的特性不变&#xff08;左<中<右)若删除结点导致不平衡&…

华为aarch64架构的泰山服务器EulerOS 2.0 (SP8)系统离线安装saltstack3003.1实践

华为泰山服务器的CPU芯片架构为aarch64&#xff0c;所装系统为EulerOS 2.0 (SP8)aarch64系统&#xff0c;安装saltstack比较困难。本文讲解通过pip安装方式离线安装saltstack3003.1以进行集中化管理和维护。 一、系统环境 1、操作系统版本 [rootlocalhost ~]# cat /etc/os-r…

MyBatis字段名和属性名不一样的解决方案

一、给字段起别名&#xff0c;保持和属性名一样 <! --List<Emp> getAllEmp( ); --><select id"getAllEmp" resultType"Emp">select eid , emp_name empName , age , sex, email from t_emp</ select>如上面的SQL语句将emp_name取别…

蓝桥杯 题库 简单 每日十题 day4

01 津津上初中了。妈妈认为津津应该更加用功学习&#xff0c;所以津津除了上学之外&#xff0c;还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴&#xff0c;而且上得越久就会越不高兴。假设津津…

产品解读 | 分布式多模数据库:KaiwuDB

1.KaiwuDB 是什么&#xff1f; KaiwuDB 是由浪潮创新研发的一款分布式、多模融合&#xff0c;支持原生 AI 的数据库产品&#xff0c;拥有“就地计算”等核心技术&#xff0c;具备高速写入、极速查询、SQL 支持、随需压缩、智能预计算、订阅发布、集群部署等特性&#xff0c;具…

DirectX12(d3d12)初始化

一、前置要求 Windows 10及以上(安装有DirectX12)VisualStudio 2022 二、DirectX12入门 1.引用头文件 #include<Windows.h> #include<d3d12.h> #include<dxgi1_4.h>2.注册窗口类并初始化窗口 这里我们调用Windows API 通过应用程序的句柄来注册一个唯一…

操作系统基本概念

目录 一、基本概述 二、操作系统的特点 &#xff08;一&#xff09;并发性&#xff08;实质是微观的串行、宏观的并行&#xff09; 1. 对比看&#xff1a;并行性 2. 单核CPU和多核CPU &#xff08;二&#xff09;共享性 &#xff08;三&#xff09;虚拟性 &#xff08;…

数字大时代 韧性向未来 | 2023数字韧性保险峰会圆满召开

2023年9月7日&#xff0c;由同创永益主办的2023数字韧性保险峰会在上海成功举办。ITSS DCMG组长肖建一等数十位保险行业专家、企业代表出席本次会议&#xff0c;同创永益与多方共同探讨保险行业数字化发展与数字韧性体系建设&#xff0c;共话行业数智化未来。 会议伊始&#xf…

Qt(day1)

思维导图 Qt实现第一个web的基础页面 #include "mywnd.h" #include "ui_mywnd.h" #include<QLabel> #include<QLineEdit> #include<qpushbutton.h>MyWnd::MyWnd(QWidget *parent): QMainWindow(parent), ui(new Ui::MyWnd) {ui->set…

【SpringSecurity】三更草堂项目案例分析3 - 鉴权操作

目录 鉴权RBAC 模型前置准备redis 实现角色权限获取 鉴权 RBAC 模型 参考 CSDN 文章 RBAC&#xff08;Role-Based Access Control&#xff09;&#xff0c;基于角色的访问控制&#xff0c;现在主流的权限管理系统的权限设计都是 RBAC 模型 所谓的 RBAC 模型&#xff0c;可以理…

农民朋友有福利啦!建行江门市分行“裕农通+农资结算”平台正式上线

随着广东广圣农业发展有限公司办公室内的裕农通“智慧眼”结算机“叮”的一声到账提醒&#xff0c;标志着全国首个“裕农通农资结算“平台的成功上线&#xff0c;也标志着建行广东省江门市分行的裕农通业务又迈上了一个新的台阶。 广东广圣农业发展有限公司&#xff08;以下简…