二维码生成,加文字处理,在非docker环境下运行正常,docker下报错。
FontMetrics类依赖了系统组件,只需安装依赖即可解决。

Docker版本 openjdk:8-jdk-alpine  Alpine没有自带默认字体造成的NullPointerException异常处理

    at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
    at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
    at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
    at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774)
    at sun.font.SunFontManager$2.run(SunFontManager.java:431)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.font.SunFontManager.<init>(SunFontManager.java:376)
    at sun.awt.FcFontManager.<init>(FcFontManager.java:35)
    at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)

代码如下:

/**
     * 生成中间加文字的二维码
     * params:content:二维码内容
     * pressText:二维码中间的文字
     */
    public static BufferedImage toTextQrcode(String pressText, String content) {

        Map<EncodeHintType,Object> hints = new HashMap<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

        BitMatrix matrix = null;
        try {
            matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 200, 200,hints);
        } catch (WriterException e) {
            e.printStackTrace();
            return null;
        }

        int width = matrix.getWidth();
        int height = matrix.getHeight();

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        try {
            pressText = new String(pressText.getBytes(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Graphics g = image.createGraphics();
        g.setColor(Color.BLACK);
        Font font = new Font(Font.SERIF, Font.BOLD, 24);
        g.setFont(font);
        FontMetrics metrics = null;
        try {
            metrics = g.getFontMetrics(font);
        } catch ( Exception e){
            e.printStackTrace();
        }

        int textWidth = metrics.stringWidth(pressText);
        int textHeight = matrix.getHeight();
        // 文字在图片中的坐标 这里设置在中间
        int startX = (WIDTH - metrics.stringWidth(pressText)) / 2;
        int startY = (HEIGHT - 40)/2;

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                if (x>startX && x<(startX+textWidth)
                    && y>startY && y<(startY+26)){
                    image.setRGB(x, y,WHITE);
                } else {
                    image.setRGB(x, y, matrix.get(x, y) == true ? BLACK : WHITE);
                }
            }
        }


        g.drawString(pressText, startX, startY+21);
        g.dispose();

        return image;
        
    }  

 
    
报错位置    

metrics = g.getFontMetrics(font);     

Alpine Linux是一个面向安全应用的轻量级Linux发行版。它采用了musl libc和busybox以减小系统的体积和运行时资源消耗,同时还提供了自己的包管理工具apk。


apk update
update:从远程镜像源中更新本地镜像源索引。
update命令会从各个镜像源列表下载APKINDEX.tar.gz并存储到本地缓存,一般在/var/cache/apk/(Alpine在该目录下)、/var/lib/apk/ 、/etc/apk/cache/下。


初次使用

RUN echo -e "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main\n\
https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/community" > /etc/apk/repositories
RUN apk --update add curl bash ttf-dejavu 
RUN rm -rf /var/cache/apk/*

      
下载超级慢,并且中断报错。      
因为文字只处理数字,无中文所以设置环境为英文,少下载些字体

ENV LANG en_US.UTF-8
RUN apk add --update ttf-dejavu fontconfig

docker打包-》运行-》测试-》通过。

非docker环境字体安装
1、Centos 系统处理:

yum install fontconfig
fc-cache --force


2、Alpine 系统处理:

apk add fontconfig
apk add --update ttf-dejavu
fc-cache --force

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐