文字图标
最近安装了一下谷歌的infinity插件,感觉它的文字图标功能非常Nice,于是想自己做一个。
业务场景:有时候,因为设计的原因,用户信息中,是没有用户头像的,或者用户暂时还不想上传头像,但是UI中又必须用头像进行占位,
这时候就可以使用文字图标,通过用户名直接生成一张图片。(参考码云的用户头像)
Java实现
核心代码如下:
public static void main(String[] args) throws IOException { BufferedImage image = createFontIcon("学习", Color.BLACK, new Font("黑体", Font.PLAIN, 48), 200, 200); ImageIO.write(image, "png", new File("C:\\Users\\postm\\Desktop\\1.png")); } /** * 生成文字图标 * * @param str 字符串 * @param color 颜色 E.G.: Color.BLACK * @param font 字体 E.G.: new Font("黑体", Font.PLAIN, 48) * @param width 宽度 * @param height 高度 */ public static BufferedImage createFontIcon(String str, Color color, Font font, Integer width, Integer height) { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); Graphics2D g = image.createGraphics(); g.setClip(0, 0, width, height); g.setColor(color); g.fillRect(0, 0, width, height); g.setColor(Color.WHITE); g.setFont(font); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); FontMetrics fm = g.getFontMetrics(font); int y = (height - font.getSize()) / 2 + fm.getAscent() - fm.getDescent(); int x = (width - fm.stringWidth(str)) / 2; g.drawString(str, x, y); g.dispose(); return image; }
将上述代码,写成一个接口,前端就可以直接调用,这里仅供参考(直接从生产环境copy下来的)。
import cn.seaboot.common.digest.Base64; import cn.seaboot.common.file.BufferedImageUtil; import cn.seaboot.common.file.IOUtils; import cn.seaboot.common.file.ResponseWriter; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * 创建文字图标 * * @author Mr.css * @date 2020-09-30 20:01:38 */ @Controller @RequestMapping(value = "/sys/icon") public class IconController { /** * 创建文字图标 * * @param txt 字符串 * @param color 背景颜色 * @param fontSize 字体大小 * @param width 宽度 * @param height 高度 * @throws IOException - */ @RequestMapping(value = "{txt}", method = RequestMethod.GET) public void create(@PathVariable String txt, HttpServletResponse response, @RequestParam(defaultValue = "#3388FF") String color, @RequestParam(defaultValue = "24") Integer fontSize, @RequestParam(defaultValue = "100") Integer width, @RequestParam(defaultValue = "100") Integer height) throws IOException { if (txt.length() > 2) { txt = txt.substring(0, 2); } String path = Base64.encodeString(txt.getBytes()); File file = new File("D:/icon" + File.separator + path); if (!file.exists()) { //这里做了个文件缓存,将生成的图片保存到磁盘,不一定非要缓存图片) int rgb = Integer.parseInt(color.substring(1), 16); BufferedImage image = BufferedImageUtil.createFontIcon(txt, new Color(rgb), new Font("黑体", Font.PLAIN, fontSize), width, height); try (OutputStream os = IOUtils.openFileOutputStream(file)) { ImageIO.write(image, "png", os); } } //将生成的图片写入IO流,按照自己项目的IO工具进行调整 try (InputStream is = IOUtils.openFileInputStream(file)) { ResponseWriter.create(response).setPreviewName(file.getName() + ".png").write(is); } } }
纯前端实现
使用画布功能,直接绘制出1个文字图标
function createFontIcon(txt, backgroundColor) { var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = backgroundColor||'#3388FF'; ctx.fillRect(0, 0, 100, 100); ctx.fillStyle = "#ffffff"; ctx.font = "28px 黑体"; if(txt.length > 4){ txt = txt.substring(0,4); var w = ctx.measureText(txt).width; if(w > 70){ txt = txt.substring(0,2); } } ctx.textAlign = "center"; ctx.fillText(txt, 50, 60); return canvas.toDataURL('image/png'); } var url = createFontIcon('demo'); document.getElementById('image').setAttribute('src', url);
效果
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!