-2

Je me demandais comment implémenter efficacement la procédure d'échelle d'image suivante en Java ou en traitement. Lors de la mise à l'échelle, les limites de l'image s'enroulent autour des bords de l'écran. Je souhaite appliquer la même chose à l'exécution à mon tableau Pixels() dans Traitement. (pour garder ce traitement agnostique - Pixels() n'est rien d'autre qu'une méthode qui retourne tous les pixels sur mon écran actuel dans un tableau). (Notez que cet exemple a été fait dans MaxMsp/Jitter en utilisant le module jit.rota, qui semble utiliser une implémentation très efficace).Java/Processing - matrice d'image à l'échelle avec des bords d'habillage

unscaled

zoomed out

Quelqu'un peut-il me aider sur la façon de commencer? Je suppose que cela doit être une combinaison de réduction d'échelle de l'image et de création de copies adjacentes - mais cela ne me semble pas très efficace. l'exemple ci-dessus fonctionne parfaitement sur les vidéos avec les paramètres les plus extrêmes.

+0

Avez-vous essayé quelque chose ?? et oubliez le très effficient ce n'est pas votre usine – gpasch

Répondre

1

Une option que je peux penser qui sera rapide utilise un fragment shader de base.

Heureusement, vous avez un exemple assez proche de ce que vous avez besoin livré avec traitement via Fichier> Exemples> Thèmes> Shaders> Infini Tiles

je ne serai pas en mesure de fournir efficacement un bon départ pour terminer le guide, mais il ya un PShader tutorial on the Processing website exhaustif si vous démarrez à partir de zéro.

GIST vraiment difficile de ce que vous avez besoin:

  • shaders sont des programmes qui fonctionnent vraiment rapide et parallélisé sur le GPU, divisé en deux: vertex shaders (deal avec la géométrie 3D principalement), fragment shader (affaire avec des "fragments" (ce qui est sur le point de devenir des pixels à l'écran) principalement). Vous aurez envie de jouer avec un fragment shader
  • Le langage est appelé GLSL et est un peu différent (moins de types, syntaxe plus stricte, plus simple), mais pas totalement étranger (type de C déclarant variables, fonctions, conditions, boucles , etc.)
  • si vous souhaitez effectuer une variable d'un programme de GLSL accessible dans le traitement vous, il préfixe avec le mot-clé uniform
  • utilisation textureWrap(REPEAT) pour envelopper les bords
  • à l'échelle de l'image et l'envelopper, vous aurez besoin pour mettre à l'échelle les coordonnées d'échantillonnage de texture:

Voici ce que le shader changeurs InfiniteTiles ressemble:

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

Vous pouvez simplifier un peu que vous ne avez pas besoin de défiler.En outre, au lieu de la soustraction et la multiplication (- TILES_COUNT_X * pos), vous pouvez simplement multiplier:

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

Avis J'ai réorientés la variable time pour devenir scale, donc le code de traitement accès à cette variable uniforme doit également changer:

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

Déplacez la souris pour changer d'échelle: fragment shader scaling normal scale

fragment shader scaling small scale

Mise à jour Vous pouvez jouer avec un shader here très similaire:

0

Je efficace ne trouver une solution - mais implémenterez la méthode de George suivant la différence de vitesse en utilisant les shaders semble valoir la peine!

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