JSem: 6.3
|
Nel numero precedente abbiamo visto l'utilizzo di MemoryImageSource e createImage(w,h) per creare immagini "dal niente". Abbiamo anche visto come manipolare immagini con MemoryImageSource e PixelGrabber. Bisogna tenere presente che queste operazioni necessitano di parecchia memoria. Per evidenziare questo fatto consideriamo il seguente programma:
import java.awt.Graphics;
import java.awt.Color;
import java.applet.*;
public class CosCol2 extends Applet{
int w,h,r,x2,y2;
public void init(){
setBackground(new Color(128,0,255));
w = getSize().width;
h = getSize().height;
}
double C(double x, double y){
return Math.cos((x*x + y*y)/6000);
}
public void paint(Graphics g){
int X0 = (w + (int)(0.707 * h))/2;
int Y0 = h/2;
for(int x = (int)(0.707*h); x < w; x++){
for(int y = 0; y < h ; y++){
x2 = (int)(x-y * 0.707);
y2 = (int)(y * 0.707 - 50*C(x - X0, y- Y0)+Y0 * 0.707/2);
r = (int)((C(x-X0, y-Y0)+1)*127);
g.setColor(new Color(r,0,128));
g.drawLine(x2,y2,x2,y2);
}
}
}
}
|
Il cui output è il seguente:
Questo programma è molto simile a Es2_Im.java del numero precedente, l'unica differenza sostanziale sta nell'introduzione di x2, y2 e nell'istruzione g.drawLine(x2,y2,x2,y2), la quale disegna un solo punto (cioè un pixel). Vediamo che ogni volta che carichiamo (o aggiorniamo) il browser, ci vuole un certo tempo prima di avere l'immagine completa e vediamo evolversi il programma che disegna a x fissato tutte le y e poi incrementa x e ricommincia: i calcoli non sono così immediati, riusciamo a seguirli sullo schermo (tra l'altro l'effetto ottenuto è assai piacevole).
La prossima applet presenta una piccola animazione fatta usando una sola immagine.
L'output è il seguente:
Questo è il codice:
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class MareMosso extends Applet implements Runnable{
Thread runner;
double inc = 0.0;
int w,h,s;
PixelGrabber pg;
int[] pix, movpix;
double C = 0.0;
int yadj = 0;
double RAD = Math.PI/180;
double ang_deg = 0.0;
double ang_rad = 0.0;
Image miaIm,img,buff_im;
Graphics m_g;
String S;
public void init(){
s = Integer.parseInt(getParameter("sleep"));
inc = Double.valueOf(getParameter("angolo")).doubleValue();
S = getParameter("Image");
img = getImage(getCodeBase(),S);
try{
MediaTracker track = new MediaTracker(this);
track.addImage(img,0);
track.waitForID(0);
}catch(InterruptedException e){};
buff_im = img;
w = img.getWidth(this);
h = img.getHeight(this);
pix = new int[w*h];
movpix = new int[w*h];
miaIm = createImage(w,h);
m_g = miaIm.getGraphics();
try{
pg = new PixelGrabber(img,0,0,w,h,pix,0,w);
pg.grabPixels();
}catch(InterruptedException e){};
}
public void paint(Graphics g){
m_g.drawImage(buff_im,0,0,this);
g.drawImage(miaIm,0,0,this);
}
public void start(){
if(runner == null){
runner = new Thread(this);
runner.start();
}
}
public void run(){
Thread thisThread = Thread.currentThread();
while(runner == thisThread) {
try{
y_moveImage();
repaint();
Thread.sleep(s);
}
catch(InterruptedException e){};
}
}
public void stop(){
if(runner != null){
runner = null;
}
}
public void y_moveImage(){
for(int i=0; i < w-1; i++){
ang_deg += inc;
if(ang_deg > 360){ ang_deg = 0;}
ang_rad = 2*ang_deg * RAD;
C = Math.cos(ang_rad);
int facriga = (w+i)/w +5;
yadj = (int)(facriga*C);
//facriga costante su ogni riga, ma C varia con i
for(int j=0; j < h-1; j++){
if( ( w*(j+yadj)+i >=0 )&&( w*(j+yadj)+i <= w*h-1)){
movpix[w*(j+yadj)+i] = pix[w*j+i];
}
}//fine for int j=0
}//fine for int i =0
buff_im = createImage(new MemoryImageSource(w,h,movpix,0,w));
}//fine metodo
public void update(Graphics g){
paint(g);
}
} |
Ci sono tre parametri: "sleep", il tempo di pausa del thread; "angolo" che misura la distorsione e "Image", l'immagine che viene manipolata. Nel metodo init(), dopo avere recuperato i parametri e caricato l'immagine, si prendono le misure dell'immagine (w,h), si creano due arrays di pixels, pix e movpix e con PixelGrabber si mettono i pixels dell'immagine nell'array pix.
L'animazione avviene nel metodo y_moveImage() il quale sostanzialmente fa la cosa seguente: prende i pixels di una colonna (a i fissato) e li sposta di modo che lungo una riga si abbia una curva sinusoidale:
I pixels dell'immagine originale sono agli incroci delle rette in nero. I nuovi pixels (quelli in rosso) sono messi nell'array movpix e poi, con createImage(new MemoryImageSource(w,h,movpix,0,w)) si crea l'immagine distorta (buff_im). Nel metodo paint, m_g disegna la nuova immagine su miaIm, e poi g, il contesto grafico dell'applet, disegna miaIm sullo schermo. E poi si ricomincia...
Per scaricare tutti i files necessari (.class, .java, .gif).
|