使用服务器上的处理在幕后创建图像 [英] Using Processing on a server to create images behind the scenes

查看:164
本文介绍了使用服务器上的处理在幕后创建图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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. 有人访问网页,处理程序开始运行

  2. 处理程序可以在幕后创建图像,然后将其保存为已知文件名

  3. 加载已知的文件名(只有在加工程序运行后才存在 - 所以,当网页完成后,怎样才能知道加载图像)

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

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.

推荐答案

我已经完成了这项工作,使用Servlet中的Processing实时渲染图像。
我发现的问题是Processing不是线程安全的,所以我必须创建多个Processing实例并将它们分享到一个队列中。

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.

这是一个用于呈现Mandelbrot分形的servlet,将被Google Maps用作覆盖:

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

}

这篇关于使用服务器上的处理在幕后创建图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆