通过上传ttf或者otf字体文件生成对应字体的图片

	由于项目需求,需要通过上传的字体文件来生成对应的图片以方便用户快速查看字体效果,经查阅信息后完成此需求,记录下此以供日后学习巩固。
	
	根据思路,首先是获取到字体文件的url,然后根据url获取到字体文件,对字体文件进行操作,最后生成图片。以下为代码部分。
	
	第一步,获取到字体文件url并通过url获取到字体文件
	
	其中,有一个根据字体长度来设置字体大小的判断,主要是因为字体字符的长度不一,所以为了防止过长字体展示不完全做了一个判断,尽量让长短不一的字体都能适应在图片内。(比如宋体是两个字,方正兰亭细黑简体有八个字)
	由于目前的需求是返回生成图片的url,故会将生成的图片上传到自己的服务器并返回图片url更新字体文件,所以会对文件进行加密等操作,处理文件名之后的可以忽略。
	设置好图片宽高后即可调用createImage生成图片(期间遇到过一个bug是在本地测试时生成的字体正常为中文,然后上服务器后却变成了英文,查了一下大致是Windows和Linux环境导致的,但不是很了解,如有大神了解,欢迎指导。最终在获取字体名称时设定了一个值解决问题Locale.SIMPLIFIED_CHINESE)。
		public void strToPic(FontFile fontfile){
			BufferedImage bufferedImage = null;
	        HttpURLConnection httpConn = null;
	        //获取问号前的地址
	        String fontUrl = fontFile.getFileUrl().split("\\?")[0];
	        //根据url获取到服务器中的字体文件
	        try {
	            URL url = new URL(fontUrl);
	            httpConn = (HttpURLConnection) url.openConnection();
	            httpConn.connect();
	            InputStream inputStream = httpConn.getInputStream();
	
	            //设定字体大小
	            float fontSize;
	            //创建font对象
	            Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
	            int fontLength = dynamicFont.getFontName().length();
	            //根据字体长度来设置字体大小
	            if(fontLength > 15){
	                fontSize = 50 ;
	            }else {
	                fontSize = 65 ;
	            }
	            Font dynamicFontPt = dynamicFont.deriveFont(fontSize);
	            //图片宽高
	            Integer width = 900;
	            Integer height = 675;
	            String type = "png";
	            //处理文件名
	            String withTypeFileName = fontFile.getFileUrl().substring(0,fontFile.getFileUrl().indexOf("?"));
	            String fileName = withTypeFileName.substring(0,withTypeFileName.indexOf("."));
	            String realFileName = fileName + "." + type;
	            String cephFileName = cephService.handleFileName(realFileName);
	            //创建图片对象
	            try {
	                bufferedImage = createImage(dynamicFontPt.getFontName(Locale.SIMPLIFIED_CHINESE), dynamicFontPt,  width, height, 0, 0);
	                if(ObjectUtils.isEmpty(bufferedImage)){
	                    throw new BusinessException("创建图片失败");
	                }
	                //上传到ceph
	                cephService.uploadFile(bufferedImage,cephFileName);
	                //获取到生成图片的url
	                String imageUrl = cephService.getFileUrlByFileName(cephFileName);
	                fontFile.setImageUrl(imageUrl);
	                fontFileMapper.updateById(fontFile);
	                //同步到es
	                esFontService.batchUpdateESFont(fontFile);
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }catch (Exception e){
	            e.printStackTrace();
	        }
		}
	第二步,生成图片
	根据第一步传入的参数调用该方法可返回一个bufferedImage对象,具体需要什么可根据自己的需求进行修改
	/**
     * 根据输入的参数在对应路径生成对应的png格式图片字体,背景为透明
     *
     * @param str     文字
     * @param font    字体类型
    //     * @param outFile 图片输出路径
     * @param width   图片宽度
     * @param height  图片高度
     * @param x       文字的横坐标(为0代表需要程序自动计算)
     * @param y       文字的纵坐标(为0代表需要程序自动计算)
     * @throws Exception Exception
     */
     private static BufferedImage createImage(String str, Font font,
                                             Integer width, Integer height, int x, int y) throws Exception {
        // 创建BufferedImage对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取Graphics2D
        Graphics2D g2d = image.createGraphics();

        // ----------  增加下面的代码使得背景透明  -----------------
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = image.createGraphics();
        // ----------  背景透明代码结束  -----------------
        //设置字体颜色
        g2d.setColor(Color.black);
        //消除字体的锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        // 设置字体类型
        g2d.setFont(font);
        //用于获得垂直居中
        FontMetrics fm = g2d.getFontMetrics(font);
        int ascent = fm.getAscent();
        int descent = fm.getDescent();
        if (x == 0) {
            x = (width - fm.stringWidth(str)) / 2;
        }
        if (y == 0) {
            y = (height - (ascent + descent)) / 2 + ascent;
        }
        // 将字符写入到图片内
        g2d.drawString(str, x, y);
        //释放对象
        g2d.dispose();
        // 保存文件
        return image;
    }
	在开发中查阅了很多资料,但由于记录此文章时离开发过于久远,故不能将相关资料逐一列举,如有侵权,请联系删除。欢迎大家一起学习!
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值