This is a fairly abstract question, so it doesn't contain an SSCCE. Basically, I wish to send a graph that I am constructing as part of a JSON String. However, to do this, I need to be able to send this component (the graph) in a format that makes sense. I was wondering if there is any such format?
Sorry for the abstractness, I just have been completely stumped.
Cheers, Kesh
To capture an image of a component, create an image, get a graphics context for the image, then ask the component to paint itself using that graphics context:
Component comp = ...;
BufferedImage image = new BufferedImage(comp.getWidth(), comp.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
comp.paint(g);
g.dispose();
(import java.awt.image.BufferedImage
if not already.)
To pack this image for transport, we can compress it in PNG format and create a Base64 encoding of the binary data:
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();
My implementation of a Base64 encoder since Java doesn't have one:
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;
}
}
You'll end up with a long string starting with "iVBOR" (the Base64-encoded form of "PNG"), which can be easily packed in a JSON object.
If you prepend the string with "data:image/png;base64,
" it becomes a valid data URI that web browsers can display directly (you can link to it or use it as an <img>
tag's src
). I'm not sure if that's a viable way to display it on an iPad but I'm sure it's possible to figure something out.