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