由于项目需求,需要通过上传的字体文件来生成对应的图片以方便用户快速查看字体效果,经查阅信息后完成此需求,记录下此以供日后学习巩固。
根据思路,首先是获取到字体文件的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];
try {
URL url = new URL(fontUrl);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.connect();
InputStream inputStream = httpConn.getInputStream();
float fontSize;
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("创建图片失败");
}
cephService.uploadFile(bufferedImage,cephFileName);
String imageUrl = cephService.getFileUrlByFileName(cephFileName);
fontFile.setImageUrl(imageUrl);
fontFileMapper.updateById(fontFile);
esFontService.batchUpdateESFont(fontFile);
} catch (Exception e) {
e.printStackTrace();
}
}catch (Exception e){
e.printStackTrace();
}
}
第二步,生成图片
根据第一步传入的参数调用该方法可返回一个bufferedImage对象,具体需要什么可根据自己的需求进行修改
private static BufferedImage createImage(String str, Font font,
Integer width, Integer height, int x, int y) throws Exception {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
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;
}
在开发中查阅了很多资料,但由于记录此文章时离开发过于久远,故不能将相关资料逐一列举,如有侵权,请联系删除。欢迎大家一起学习!