5

我看到大多数人使用处理的方式是将图像直接绘制到客户端的屏幕或网页上。

如何在没有可视画布的情况下使用处理创建图像,然后将此图像保存到文件中?

以下是我感兴趣的具体步骤:

  1. 有人访问网页,导致处理程序开始运行
  2. 处理程序将在幕后工作以创建图像,然后将其保存为已知文件名
  3. 网页将加载已知的文件名(仅在处理程序运行后才存在 - 那么,网页如何知道在完成后加载图像?)

我假设 Processing 程序正在服务器上运行(这与 Processing 通常的工作方式相反),并且文件将存储在服务器上。我还假设处理程序中的一些代码来限制创建的文件数量 - 例如,如果在 5 分钟内创建现有图像,它将不会创建新图像。

4

5 回答 5

10

我已经做到了这一点,使用 Servlet 中的处理来动态渲染图像。我发现的一个问题是 Processing 不是线程安全的,所以我必须创建多个 Processing 实例并在队列中共享它们。

这是一个呈现 Mandelbrot 分形的 servlet,供 Google 地图用作叠加层:

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

}
于 2010-01-05T14:27:17.223 回答
2

如果我没记错的话,Processing 最初是为 Java 编写的。然后将其移植到 Javascript。您可以使用 Java 来创建图像。

于 2009-12-11T18:15:00.687 回答
1

您可以在此处下载处理的 java 版本并使用它。处理不限于javascript。正如 Ben 提到的,它最初是一个 java 程序。主页还列出了 javascript、clojure、ruby 和 scala 中的实现。

如何将其集成到网页的其余部分主要取决于您的 Web 框架。

于 2009-12-11T18:38:31.923 回答
0

您可以在服务器上运行一个 javascript 引擎并像在浏览器中使用它一样使用处理。

以下是安装 v8 解释器的方法:

独立运行 v8 Javascript 引擎。

我不太确定这是否允许您访问文件,但我确信有办法做到这一点。

于 2009-12-11T18:37:47.427 回答
0

处理是Java。2.0 (beta x) 中新增的 javaScript 模式是processingjs的集成,这是一个将处理代码“预处理”到 javaScript 中的库。实际上功能较少,并且没有兼容的处理库。这是来自 Processing 开发人员关于 2.0 中此更改的内容:

从 2.0 alpha 7 开始,Java Applet 支持已被删除。考虑到我们的优先级,缺乏 Web 浏览器支持,支持这些根本没有意义......而浏览器制造商和操作系统供应商使小程序变得更加困难没有吸引力是一场失败的战斗......目前,对于在网络上运行的东西来说,使用 Processing JS(或 Processing 1.5)通常是一个更好的选择...... (见全文)

Processing wiki 中有这篇文章介绍如何使用 PHP 将文件保存到服务器。不确定它是否有帮助。

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

于 2012-10-03T22:57:57.807 回答