• 文字图标


    最近安装了一下谷歌的infinity插件,感觉它的文字图标功能非常Nice,于是想自己做一个。


    业务场景:有时候,因为设计的原因,用户信息中,是没有用户头像的,或者用户暂时还不想上传头像,但是UI中又必须用头像进行占位,
    这时候就可以使用文字图标,通过用户名直接生成一张图片。(参考码云的用户头像)

    直接给<div>填充背景色,然后加个白色文字,也能做出这种效果。
    将Html标签做成<img>的样子,和,生成1张图片,然后放到<img>,这2种做法有着本质的区别:
    在未来的代码调整中,如果已经使用<img>,改动的只是一个src,而其他标签做成<img>的样子,则需要重新调整代码。

    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;
        }

    将上述代码,写成一个接口,前端就可以直接调用。

     cn.seaboot.common.core的相关代码,可以在 https://gitee.com/seaboot/common 页面下载。

    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()) {
                //不存在则重新创建图标(BufferedImage也可以直接写入到response,不一定非要缓存图片)
                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);
                }
            }
            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);

    效果

     

  • 相关阅读:
    sql server不存在或访问被拒绝
    维护Sql Server中表的索引
    雷声大雨点小-参加江西省网站内容管理系统培训有感
    关于WINFORM中输入法的设置
    虚拟主机下asp.net 2.0的导航控件treeview,menu等出错。
    css背景图片不重复
    网上寻宝惊魂记
    一个不大注意的存储过程的小细节。
    css——之三行三列等高布局
    今天才发现ff不支持navigate。
  • 原文地址:https://www.cnblogs.com/chenss15060100790/p/13843354.html
Copyright © 2020-2023  润新知