题
我看到大多数人使用的方式 加工 用于将图像直接绘制到客户端的屏幕或网页上。
如何使用处理在没有视觉画布的情况下创建图像,然后将该图像保存到文件中?
以下是我感兴趣的具体步骤:
- 有人访问网页,导致处理程序开始运行
- 处理程序将在幕后工作以创建图像,然后将其保存到已知的文件名
- 网页将加载已知的文件名(该文件名仅在处理程序运行后才存在 - 那么,网页如何知道在完成后加载图像?)
我假设处理程序正在服务器上运行(这与处理通常的工作方式相反),并且文件将存储在服务器上。我还假设处理程序中的某些代码可以限制创建的文件数量 - 例如,如果在 5 分钟内创建现有图像,则它不会创建新图像。
解决方案
我已经做到了这一点,使用 Servlet 中的处理来动态渲染图像。我发现的一个问题是处理不是线程安全的,因此我必须创建多个处理实例并在队列中共享它们。
下面是一个渲染 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();
}
}
}
其他提示
如果我没记错的话,Processing 最初是为 Java 编写的。然后它被移植到Javascript。您可以使用 Java 来创建图像。
您可以下载Processing的java版本 这里 并使用它。处理不限于javascript。正如 Ben 提到的,它最初是一个 java 程序。主页还列出了 javascript、clojure、ruby 和 scala 的实现。
如何将其集成到网页的其余部分主要取决于您的网络框架。
您可以在服务器上运行 JavaScript 引擎并使用处理功能,就像在浏览器中使用它一样。
安装 v8 解释器的方法如下:
我不太确定这是否允许您访问文件,但我确信有办法做到这一点。
处理是Java。2.0(beta x)中的新 javaScript 模式集成了 处理js 一个将处理代码“预处理”为 javaScript 的库。实际上功能较少,并且没有兼容的处理库。这是来自 Process 开发人员关于 2.0 中的这一变化的信息:
从 2.0 alpha 7 开始,Java Applet 支持将被删除。鉴于我们的优先级,缺乏网络浏览器支持,支持这些东西根本没有意义,...虽然浏览器制造商和OS供应商使Applet更加困难和不吸引人是一场失败的战斗...目前,使用处理JS(或处理1.5)通常是在网络上运行的事物的更好选择... (见全文)
在Processing wiki中有一篇关于如何使用PHP将文件保存到服务器的文章。不确定是否有帮助。