Ich habe dies mit der Verarbeitung in einem Servlet zum Rendern von Bildern im laufenden Betrieb getan. Ein Problem, das ich fand, ist, dass die Verarbeitung nicht threadsicher ist, also musste ich mehrere Verarbeitungsinstanzen erstellen und sie in einer Warteschlange teilen.
Hier ist ein Servlet, die Mandelbrots Fraktale macht, als Overlay von Google Maps verwendet werden:
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import processing.core.PApplet;
public class Tile extends HttpServlet {
private static final long serialVersionUID = 1L;
private static LinkedBlockingQueue<PApplet> pQueue = new LinkedBlockingQueue<PApplet>();
private PApplet createPApplet() {
PApplet p = new PApplet();
p.init();
p.size(256, 256);
p.noLoop();
p.textFont(p.createFont("Monospace", 8, true));
p.stroke(0x22FFFFFF);
p.colorMode(PApplet.HSB, 256, 1, 1);
return p;
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PApplet p;
if (pQueue.size() == 0) {
p = createPApplet();
} else {
try {
p = pQueue.take();
} catch (InterruptedException e) {
p = createPApplet();
}
}
int zoom = Integer.parseInt(request.getParameter("z"));
int tileX = Integer.parseInt(request.getParameter("x"));
int tileY = Integer.parseInt(request.getParameter("y"));
int tiles = 1 << zoom;
p.loadPixels();
final int N = 256;
//final double inverse_N = 2.0/256;
final double inverse_N = 2.0/tiles/256;
int y = -1;
while ((++y) < N) {
double Civ = (double) (y + tileY * 256) * inverse_N - 1.0;
for (int x = 0; x < N; x++) {
double Crv = (double) (x + tileX * 256) * inverse_N - 1.5;
double Zrv = Crv;
double Ziv = Civ;
double Trv = Crv * Crv;
double Tiv = Civ * Civ;
int i = 256;
do {
Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
Zrv = Trv - Tiv + Crv;
Trv = Zrv * Zrv;
Tiv = Ziv * Ziv;
} while (((Trv + Tiv) <= 4.0) && (--i > 0));
if (i == 0) {
p.pixels[x + y * N] = 0x00000000;
} else {
p.pixels[x + y * N] = p.color(256 - i,1,1);
}
} // end foreach column
}
p.updatePixels();
// render info
p.fill(0x22000000);
p.text("X: " + tileX + "\nY: " + tileY + "\nZ: " + zoom, 1, 13);
p.fill(0x22FFFFFF);
p.text("X: " + tileX + "\nY: " + tileY + "\nZ: " + zoom, 0, 12);
p.line(0, 0, 0, 2);
p.line(0, 0, 2, 0);
p.line(255, 255, 255, 253);
p.line(255, 255, 253, 255);
// done
p.loadPixels();
BufferedImage img = new BufferedImage(256, 256,
BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, 256, 256, p.pixels, 0, 256);
p.draw();
response.setHeader("Content-Type", "image/png");
ImageIO.write(img, "PNG", response.getOutputStream());
try {
pQueue.put(p);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Warum wählen Sie Verarbeitung für die Aufgabe, anstatt lassen die Aufgabe, die Wahl der Sprache direkt helfen? –
gültige Frage. Ich mag Processing, weil es nicht-triviale Grafiken einfach zu erstellen macht. Aber ich nehme an, ich bin nicht daran gebunden, wenn es im System keinen Sinn macht (versuche ich einen quadratischen Stift in ein rundes Loch zu stecken?) –
Abhängig von der Komplexität des Bildes und der Zeit zu rendern, du könnte in Erwägung ziehen, mit processing.js das Bild am Frontend im Canvas zu rendern. – JAMESSTONEco