开发者

Using Processing on a server to create images behind the scenes

The way I see most people use Processing is for drawing an image directly onto a screen or webpage on the client side.

How would one use Processing to create an image without a visual canvas, then save this image to a file?

Here are the specific steps I'm interested in:

    开发者_如何学Python
  1. Someone visits a webpage, which causes the Processing program to start running
  2. The Processing program would work behind the scenes to create an image, then save it to a known filename
  3. The webpage would load the known filename (which only exists after the Processing program is run - so, how can the webpage know to load the image when it's finished?)

I'm assuming that the Processing program is running on a server (which is contrary to how Processing usually works), and the file will be stored on the server. I'm also assuming some code in the Processing program to throttle the number of files that are created - for example, it won't create a new image if an existing image was created within 5 minutes.


I've done this, using Processing in a Servlet to render images on the fly. A problem I found is that Processing isn't thread-safe, so I had to create multiple Processing instances and share them in a queue.

Here's a servlet which renders Mandelbrot fractals, to be used by Google Maps as an overlay:

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();
        }
    }

}


Processing was originally written for Java if I remember correctly. It was then ported to Javascript. You could use Java to create the image.


You could download the java version of Processing here and use that. Processing is not limited to javascript. As Ben mentions, it started as a java program. The homepage also lists implementations in javascript, clojure, ruby, and scala.

How to integrate this into the rest of your web page depends mostly on your web framework.


You could run a a javascript engine on the server and use processing just like you'd use it in the browser.

Here's how you can install the v8 interpreter:

Running v8 Javascript Engine standalone.

I'm not quite sure if this allows you to access files, but I'm sure there are ways to do this.


Processing is Java. The javaScript mode, new in 2.0 (beta x) is an integration of processingjs a library that "pre processes" Processing code into javaScript. Actually there is less features and none processing library is compatible. This is from Processing developers about this change in 2.0:

Java Applet support is being removed, starting in 2.0 alpha 7. It simply doesn't make sense to support these anymore, given our priorities, lack of web browser support, ... while browser makers and OS vendors make applets all the more difficult and unappealing is a losing battle ... At the moment, using Processing JS (or Processing 1.5) is instead generally a better option for things that run on the web... (see full text)

There is this article in Processing wiki about how to use PHP to save files to server. Not sure if it can help.

http://wiki.processing.org/w/Saving_files_to_a_web-server

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜