java uses Graphics2D to draw and drawing mode

  • 2021-12-12 04:28:48
  • OfStack

Directory 1. The author encountered the need to generate shared posters in the development process 2. Graphics2D commonly used API3. On talent 4. Output picture 5. Summary

1. The author encountered the need to generate shared posters in the development process

Need the back-end to dynamically generate the sharing diagram (finally, the front-end realizes it itself, haha); Record some problems and solutions encountered in the process.

2. Graphics2D Common API

First get the Graphics2D instance


BufferedImage bi = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = bi.createGraphics();
//  Turn on anti-aliasing 
RenderingHints renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
//  Use high quality compression 
renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics.setRenderingHints(renderingHints);

1. graphics. drawImage (). Add a picture to the canvas. The parameters are position and width and height of the picture


BufferedImage bgmImage = ImageIO.read(new ByteArrayInputStream(FileUtils.readFileToByteArray(new File("filePath"))));
graphics.drawImage(bgmImage, x, y, width, height, null);

2. graphics. drawString (), add text to the canvas (word wrap needs to be implemented by yourself)


graphics.setFont(new Font("PingFangSC-Regular", Font.PLAIN, 24));
graphics.setColor(Color.WHITE);
graphics.drawString(title, x, y);

3. graphics. fillRoundRect (), rounded rectangle with background color (used to draw background color for words, pay attention to drawing rectangular background first, and then drawing words), and the last two parameters are to set rounded radian


//  Background color rectangle 
graphics.setColor(new Color(254, 68, 82));
graphics.fillRoundRect(x, y, width, height, 4, 4);

3. Talent

1. The automatic line wrap of painting text just mentioned needs to be realized by itself. Here, I will briefly talk about the realization principle; In fact, according to the set line width and the string to be drawn, do a calculation. The line width of each text can be obtained, so that you can calculate how many words can be displayed in each line, and then you can calculate how many lines are displayed in total. Finally, just call the graphics. drawString () method to draw it; The following is the core code for line wrapping:


   private static int drawStringAutoLineFeed(Graphics g, String strContent, int rowWidth, int x, int y) {
        String[] split = strContent.split("\n");
        int total = 0;
        for (String str : split) {
            int height = drawStringAutoLine(g, str, rowWidth, x, y);
            total += height;
            y += height;
        }
        return total;
    }
 
    /**
     *  Wrap lines according to the specified width 
     * 
     * @param g
     * @param rowWidth
     * @param strContent
     * @param x
     * @param y
     */
    private static int drawStringAutoLine(Graphics g, String strContent, int rowWidth, int x, int y) {
        //  Get String   Total width of characters 
        int strWidth = getStringLength(g, strContent);
        //  Get character height 
        int strHeight = getStringHeight(g);
        //  Total number of strings 
        int rows = 0;
        if (strWidth > rowWidth) {
            int rowStrNum = getRowStrNum(strContent.length(), rowWidth, strWidth);
            rows = getRows(strWidth, rowWidth);
            String temp = "";
            for (int i = 0; i < rows; i++) {
                //  Object for each row String
                if (i == rows - 1) {
                    //  Finally 1 Row 
                    temp = strContent.substring(i * rowStrNum, strContent.length());
                } else {
                    temp = strContent.substring(i * rowStrNum, i * rowStrNum + rowStrNum);
                }
                if (i > 0) {
                    //  No. 1 1 Line does not need to increase character height, and every subsequent 1 When a line wraps, it needs to increase the character height 
                    y = y + strHeight;
                }
                g.drawString(temp, x, y);
            }
        } else {
            //  Direct rendering 
            g.drawString(strContent, x, y);
        }
        return strHeight * rows;
    }
 
    private static int getDrawStringAutoLineHeight(Graphics g, String strContent, int rowWidth) {
        String[] split = strContent.split("\n");
        int height = 0;
        for (String str : split) {
            //  Get String   Total width of characters 
            int strWidth = getStringLength(g, str);
            //  Get character height 
            height += getStringHeight(g) * getRows(strWidth, rowWidth);
        }
        return height;
    }
 
    private static int getStringLength(Graphics g, String str) {
        char[] strChar = str.toCharArray();
        return g.getFontMetrics().charsWidth(strChar, 0, str.length());
    }
 
    //  Every 1 Number of line characters 
    private static int getRowStrNum(int strNum, int rowWidth, int strWidth) {
        int rowsNum = 0;
        rowsNum = (rowWidth * strNum) / strWidth;
        return rowsNum;
    }
 
    //  Character lines 
    private static int getRows(int strWidth, int rowWidth) {
        int rows = 0;
        if (strWidth % rowWidth > 0) {
            rows = strWidth / rowWidth + 1;
        } else {
            rows = strWidth / rowWidth;
        }
        return rows;
    }
 
    //  Character height 
    private static int getStringHeight(Graphics g) {
        return g.getFontMetrics().getHeight();
    }

Usage:


graphics.setFont(new Font("PingFangSC-Regular", Font.PLAIN, 12));
graphics.setColor(Color.GRAY);
drawStringAutoLineFeed(graphics, strContent, rowWidth, x, y);

4. Output pictures

1. Output picture byte array


ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(bi, "jpg", outputStream);
return outputStream.toByteArray();

2. Output picture files directly


ImageIO.write(bi, "jpg", new File("outFilePath"));

STEP 5 Summarize

1. Simple scenes with fixed size and style pictures are better

2. The debugging process is very disgusting, and pictures are constantly generated to see the effect

3. The recommendation of more responsible style makes the front-end html2image, which has been realized by my front-end colleagues, and the effect is much better than the back-end drawing!


Related articles: