Java 将多行多页格式的文本呈现到BuffereImage(不在Android中)

Java 将多行多页格式的文本呈现到BuffereImage(不在Android中),java,text,bufferedimage,Java,Text,Bufferedimage,我刚刚实现了一个PNG图像的创建,渲染出一个文本文件的内容。在网上搜索时,我发现了一些使用Android的实现,但没有使用标准Java的多行文本的完整示例,所以我认为值得在这里发布我的解决方案 这些要求是: 获取一个任意大小的字符串,并使用格式正确的段落将其渲染出来,以适合PNG图像,将字符串正确地拆分为行和段落。如果呈现的文档不适合一个页面,则生成多个BuffereImage,每个页面一个。我在Java文档中找到了一些用于呈现段落的示例代码,在此基础上,我做了以下工作: private sta

我刚刚实现了一个PNG图像的创建,渲染出一个文本文件的内容。在网上搜索时,我发现了一些使用Android的实现,但没有使用标准Java的多行文本的完整示例,所以我认为值得在这里发布我的解决方案

这些要求是:


获取一个任意大小的字符串,并使用格式正确的段落将其渲染出来,以适合PNG图像,将字符串正确地拆分为行和段落。如果呈现的文档不适合一个页面,则生成多个BuffereImage,每个页面一个。

我在Java文档中找到了一些用于呈现段落的示例代码,在此基础上,我做了以下工作:

private static final Font FONT = new Font("Serif", Font.PLAIN, 14);
private static final float PARAGRAPH_BREAK = 10;
private static final float MARGIN = 20;

private Graphics2D setupGraphics(BufferedImage img) {
    Graphics2D g2d = img.createGraphics();
    g2d.setFont(FONT);
    g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
    g2d.setColor(Color.BLACK);
    return g2d;
}

private List<BufferedImage> renderText(String str, int width, int height) {
    String[] paragraphs = str.split("\n");

    List<BufferedImage> images = new ArrayList<>();

    BufferedImage img = new BufferedImage(width, 
            height, 
            BufferedImage.TYPE_3BYTE_BGR);
    images.add(img);
    Graphics2D g2d = setupGraphics(img);

    float drawPosY = 0;

    for (int paragraph=0;paragraph<paragraphs.length;paragraph++) {

        drawPosY += PARAGRAPH_BREAK;

        AttributedString attStr = new AttributedString(paragraphs[paragraph]);
        AttributedCharacterIterator it = attStr.getIterator();
        LineBreakMeasurer measurer = new LineBreakMeasurer(it, g2d.getFontRenderContext());
        measurer.setPosition(it.getBeginIndex());

        while (measurer.getPosition() < it.getEndIndex()) {
            TextLayout layout = measurer.nextLayout(img.getWidth()-MARGIN*2);

            if (drawPosY > img.getHeight() - layout.getAscent() - layout.getDescent() - layout.getLeading()) {
                drawPosY = 0;
                img = new BufferedImage((int)(
                        width, 
                        height, 
                        BufferedImage.TYPE_3BYTE_BGR);
                images.add(img);
                g2d.dispose();
                g2d = setupGraphics(img);
            }

            drawPosY += layout.getAscent();

            layout.draw(g2d, MARGIN, drawPosY);

            drawPosY += layout.getDescent()+layout.getLeading();
        }
    }
    g2d.dispose();

    return images;
}
本节中几乎相同的代码将导致ImageIO以不同的格式写入文件,例如jpg而不是png,或者使用FileOutputStream而不是ByteArrayOutputStream将图像写入文件

我希望这能帮助其他有同样问题的人

    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        ImageIO.write(output, "png", baos);
        ret.setImageData(baos.toByteArray());
    } catch (IOException ex) {
        Logger.getLogger(ImageGenerationService.class.getName()).log(Level.SEVERE, null, ex);
        return null;
    }