将JComponent发送为图像

时间:2013-11-29 14:43:59

标签: java json image jcomponent

这是一个相当抽象的问题,因此它不包含SSCCE。基本上,我希望发送一个我正在构建的图形作为JSON字符串的一部分。但是,要做到这一点,我需要能够以有意义的格式发送此组件(图形)。我想知道是否有这样的格式?

对于摘要感到抱歉,我一直都很难过。

干杯, 凯什

1 个答案:

答案 0 :(得分:1)

要捕获组件的图像,创建图像,获取图像的图形上下文,然后让组件使用该图形上下文绘制自己:

Component comp = ...;
BufferedImage image = new BufferedImage(comp.getWidth(), comp.getHeight(),
    BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
comp.paint(g);
g.dispose();

(导入java.awt.image.BufferedImage,如果还没有。)

要打包此图像以进行传输,我们可以将其压缩为PNG格式并创建二进制数据的Base64编码:

StringBuilder sb = new StringBuilder();
try (OutputStream out = new Base64Encoder(sb)) {
    javax.imageio.ImageIO.write(image, "png", out);
} catch (IOException e) {
    throw new RuntimeException(e);
}
String imageData = sb.toString();

我实现的Base64编码器,因为Java没有:

import java.io.*;

public class Base64Encoder extends OutputStream {
    private Appendable out;
    private int p = 0, tmp = 0;
    private static final char[] charMap =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        .toCharArray();

    public Base64Encoder(Appendable out) {
        this.out = java.util.Objects.requireNonNull(out);
    }

    @Override
    public void write(int b) throws IOException {
        b &= 0xFF;
        if (p == 0) {
            out.append(charMap[b >> 2]);
            tmp = (b & 0x3) << 4;
            p = 1;
        } else if (p == 1) {
            out.append(charMap[tmp | (b >> 4)]);
            tmp = (b & 0xF) << 2;
            p = 2;
        } else {
            out.append(charMap[tmp | (b >> 6)]);
            out.append(charMap[b & 0x3F]);
            p = 0;
        }
    }

    @Override
    public void close() throws IOException {
        if (p != 0) {
            out.append(charMap[tmp]);
            if (p == 1) out.append('=').append('=');
            if (p == 2) out.append('=');
        }
        out = null;
    }
}

你最终会得到一个以“iVBOR”(Base64编码形式的“PNG”)开头的长字符串,它可以很容易地打包在JSON对象中。

如果您在字符串前加上“data:image/png;base64,”,那么它就会成为网络浏览器可以直接显示的有效data URI(您可以链接到它或将其用作<img>代码{{ 1}})。我不确定这是否是一种在iPad上显示它的可行方式,但我确信它可以解决问题。