Domanda

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

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top