English 中文(简体)
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:

  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 + "
Y: " + tileY + "
Z: " + zoom, 1, 13);
        p.fill(0x22FFFFFF);
        p.text("X: " + tileX + "
Y: " + tileY + "
Z: " + 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





相关问题
CSS working only in Firefox

I am trying to create a search text-field like on the Apple website. The HTML looks like this: <div class="frm-search"> <div> <input class="btn" type="image" src="http://www....

image changed but appears the same in browser

I m writing a php script to crop an image. The script overwrites the old image with the new one, but when I reload the page (which is supposed to pickup the new image) I still see the old one. ...

Firefox background image horizontal centering oddity

I am building some basic HTML code for a CMS. One of the page-related options in the CMS is "background image" and "stretch page width / height to background image width / height." so that with large ...

Separator line in ASP.NET

I d like to add a simple separator line in an aspx web form. Does anyone know how? It sounds easy enough, but still I can t manage to find how to do it.. 10x!

热门标签