代码之家  ›  专栏  ›  技术社区  ›  David Koelle

在服务器上使用处理在后台创建图像

  •  5
  • David Koelle  · 技术社区  · 15 年前

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

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

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

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

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

    5 回复  |  直到 11 年前
        1
  •  10
  •   George Bashi    11 年前

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

    下面是一个servlet,它呈现了Mandelbrot分形,供谷歌地图用作覆盖:

    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();
            }
        }
    
    }
    
        2
  •  2
  •   Ben Shelock    15 年前

    如果我没记错的话,处理最初是为Java编写的。然后它被移植到javascript。可以使用Java来创建图像。

        3
  •  1
  •   Peter Recore    15 年前

    您可以下载Java版本的处理 here 用那个。处理不限于javascript。正如本提到的,它从Java程序开始。主页还列出了JavaScript、Clojure、Ruby和scala中的实现。

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

        4
  •  0
  •   Community THelper    7 年前

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

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

    Running v8 Javascript Engine standalone.

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

        5
  •  0
  •   j0k BlackMario    12 年前

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

    Java Applet支持正在被移除,从2 alpha 7开始。它 因为我们的 优先级,缺少Web浏览器支持…而浏览器制造商和 操作系统供应商使小程序变得更加困难,而不吸引人的是 输掉战斗…目前,使用处理JS(或处理 1.5)通常是在网络上运行的更好的选择… (see full text)

    在处理wiki时,有一篇关于如何使用php将文件保存到服务器的文章。不确定是否有帮助。

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