-2

我一直想知道如何在Java或处理中有效地实现下面的图像缩放程序。缩小时,图像的边界将环绕屏幕边缘。我想在运行时将其应用于Processing中的Pixels()数组。 (为了保持这个Processing不可知 - 像素()只是一个返回数组当前屏幕上所有像素的方法)。Java /处理 - 包装边缘的缩放图像矩阵

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

unscaled

zoomed out

谁能帮助我如何开始?我认为它必须是缩小图像尺寸和创建相关副本的组合 - 但这对我来说听起来不是很有效。上面的例子完美地适用于即使是最极端设置的视频。

+0

你有试过什么?并忘记这非常effficient这不是你的工厂 – gpasch

回答

1

我能想到的一个选择是快速使用基本片段着色器。

幸运的是,你已经有了相当接近你所需要的是通过文件>例子>专题>着色器附带处理>无限瓷砖

我将无法有效地提供一个体面的启动为例以完成指导,但 如果你是从头开始,那么有一个详尽的PShader tutorial on the Processing website

一个非常粗略的,你需要什么要点:

  • 着色器是运行非常快和并行化在GPU上,分为两个项目:顶点着色器(处理三维几何图形为主),片段着色器(交易与“片段”(主要是什么将成为屏幕上的像素))。你会想玩一个片段着色器
  • 该语言被称为GLSL,并且有点不同(语法更少,类型更严格,语法更简单),但并不完全陌生(类似C类型的声明变量,函数,条件,循环等)
  • ,如果你想从加工访问的GLSL程序进行变量,你用关键字uniform
  • 使用textureWrap(REPEAT)前缀它来包裹边缘
  • 缩放图像,并把它包起来,你需要缩放纹理采样坐标:

这里的InfiniteTiles滚动着色器是什么样子:

//--------------------------------------------------------- 
// 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_COUNT_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); 
} 

通知我已经改变用途的time变量成为scale,因此处理代码访问该匀变速也必须改变:

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

移动鼠标来改变比例尺: fragment shader scaling normal scale

​​

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

0

我没有有效地想出了一个解决方案 - 但将执行下一作为使用着色器的速度差乔治的方法似乎是值得的!

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