Java/Processing-带环绕边的缩放图像矩阵

Java/Processing-带环绕边的缩放图像矩阵,java,image-processing,processing,image-scaling,max-msp-jitter,Java,Image Processing,Processing,Image Scaling,Max Msp Jitter,我一直想知道如何在Java或Processing中高效地实现下面的图像缩放过程。向外缩放时,图像的边界环绕屏幕边缘。我希望在运行时将其应用于处理中的像素()数组。(为了保持这种处理不可知,Pixels()就是一种以数组形式返回当前屏幕上所有像素的方法) (请注意,此示例是使用jit.rota模块在MaxMsp/Jitter中创建的,该模块似乎使用了非常高效的实现) 有人能帮我开始吗?我想这一定是缩小图像尺寸和创建其相邻副本的组合——但这听起来不是很有效。上面的示例在具有最极端设置的视频上也能

我一直想知道如何在Java或Processing中高效地实现下面的图像缩放过程。向外缩放时,图像的边界环绕屏幕边缘。我希望在运行时将其应用于处理中的像素()数组。(为了保持这种处理不可知,Pixels()就是一种以数组形式返回当前屏幕上所有像素的方法)

(请注意,此示例是使用jit.rota模块在MaxMsp/Jitter中创建的,该模块似乎使用了非常高效的实现)


有人能帮我开始吗?我想这一定是缩小图像尺寸和创建其相邻副本的组合——但这听起来不是很有效。上面的示例在具有最极端设置的视频上也能完美运行。

我认为最快的一个选项是使用基本片段着色器

幸运的是,通过文件>示例>主题>着色器>无限瓷砖

我无法有效地提供一个良好的从开始到结束的指南,但是 如果你从零开始,有一个详尽的答案

你需要什么的大致要点:

  • 着色器是在GPU上运行速度非常快且并行的程序,分为两部分:顶点着色器(主要处理3d几何体)和片段着色器(主要处理“片段”(即将成为屏幕上的像素)。您将需要使用片段着色器
  • 这种语言叫做GLSL,有点不同(类型更少,语法更严格,更简单),但不是完全陌生(类似于C类型的声明变量、函数、条件、循环等)
  • 如果要使GLSL程序中的变量在处理过程中可访问,请使用关键字
    uniform
  • 用于包裹边
  • 要缩放图像并将其包裹,需要缩放纹理采样坐标:
以下是InfiniteTiles scroller着色器的外观:

//---------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//---------------------------------------------------------

uniform float time;
uniform vec2 resolution;
uniform sampler2D tileImage;

#define TILES_COUNT_X 4.0

void main() {
  vec2 pos = gl_FragCoord.xy - vec2(4.0 * time);
  vec2 p = (resolution - TILES_COUNT_X * pos) / resolution.x;
  vec3 col = texture2D (tileImage, p).xyz;
  gl_FragColor = vec4 (col, 1.0);
}
您可以简化这一点,因为您不需要滚动。此外,您不需要进行减法和乘法(
-TILES\u COUNT\u X*pos
),只需进行乘法即可:

//---------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//---------------------------------------------------------

uniform float scale;
uniform vec2 resolution;
uniform sampler2D tileImage;

void main() {
  vec2 pos = gl_FragCoord.xy * vec2(scale);
  vec2 p = (resolution - pos) / resolution.x;
  vec3 col = texture2D (tileImage, p).xyz;
  gl_FragColor = vec4 (col, 1.0);
}
请注意,我已将
时间
变量重新调整为
比例
,因此访问此统一变量的处理代码也必须更改:

//-------------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//-------------------------------------------------------------

PImage tileTexture;
PShader tileShader;

void setup() {
  size(640, 480, P2D);
  textureWrap(REPEAT);
  tileTexture = loadImage("penrose.jpg");
  loadTileShader();
}

void loadTileShader() {  
  tileShader = loadShader("scroller.glsl");
  tileShader.set("resolution", float(width), float(height));  
  tileShader.set("tileImage", tileTexture);
}

void draw() {
  tileShader.set("scale", map(mouseX,0,width,-3.0,3.0));
  shader(tileShader);
  rect(0, 0, width, height);
}
移动鼠标以更改比例:


更新您可以使用非常类似的着色器:

我确实提出了一个解决方案,但下一步将实施George的方法,因为使用着色器的速度差异似乎是值得的

public void scalePixels(double wRatio,double hRatio, PGraphics viewPort) {
    viewPort.loadPixels();
    int[] PixelsArrayNew = viewPort.pixels.clone();
    double x_ratio = wRatio ;
    double y_ratio = hRatio ;
    double px, py ;
    for (int i=0;i<viewPort.height;i++) {
        for (int j=0;j<viewPort.width;j++) {
            px = Math.floor(j%(wRatio*viewPort.width)/x_ratio) ;
            py = Math.floor(i%(hRatio*viewPort.height)/y_ratio) ;
            viewPort.pixels[(int)(i*viewPort.width)+j] = PixelsArrayNew[(int)((py*viewPort.width)+px)] ;
        }
    }
    viewPort.updatePixels();    
}
public void比例像素(双圈、双圈、PGraphics视口){
loadPixels();
int[]PixelsArrayNew=viewPort.pixels.clone();
双倍x_比率=wRatio;
双y_比=hRatio;
双px,py;

因为(inti=0;我已经试过了吗?)忘记了这不是你的工厂