// ---------------------------------------------------------------------------- // application: Diffuse demo // author: Pavel Tisnovsky // file name: Diffuse7.java // directory: java // date: 25.07.2004 // description: Demonstracni aplikace pro vytvoreni a zobrazeni fraktalniho // objektu, ktery je zalozeny na simulaci difuze. Pri vytvareni // difuze se postupne generuji body, jez se spojite pohybuji // v zadane bitmape a tvori v ni tak cestu. Pocatek generovani // techto bodu lezi na kruznici, ktera se postupne zvetsuje od // stredu vznikajiciho obrazce difuze. // ---------------------------------------------------------------------------- // Nasledujici radky jsou urceny pro spusteni appletu v programu AppletViewer: // // <applet code="Diffuse7.class" width="640" height="400"> // </applet> // // pro kompatibilitu se starsi JVM firmy Microsofti se musi provest preklad // pomoci prikazu: // javac -target 1.1 Diffuse7.java // ---------------------------------------------------------------------------- // seznam importovanych balicku // ---------------------------------------------------------------------------- import java.util.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.applet.Applet; // ---------------------------------------------------------------------------- // Trida pro aplikaci filtru na zvolenou zdrojovou pixmapu. Vysledek se uklada // do cilove pixmapy. // ---------------------------------------------------------------------------- class Filter { private int imageWidth; // velikost zpracovavanych pixmap private int imageHeight; private int pixelSrc[]; // zdrojova pixmapa private int pixelDest[]; // cilova pixmapa // ------------------------------------------------------------------------ // V konstruktoru se nastavi velikost filtru a zdrojova a cilova pixmapa. // ------------------------------------------------------------------------ public Filter(int imageWidth, int imageHeight, int pixelSrc[], int pixelDest[]) { this.imageWidth=imageWidth; // nastavit velikost pixmapy this.imageHeight=imageHeight; this.pixelSrc=pixelSrc; // nastavit handle zdrojove this.pixelDest=pixelDest; // a cilove pixmapy } // ------------------------------------------------------------------------ // Nastaveni nove sirky zpracovavane pixmapy. // ------------------------------------------------------------------------ public void setImageWidth(int imageWidth) { this.imageWidth=imageWidth; } // ------------------------------------------------------------------------ // Nastaveni nove vysky zpracovavane pixmapy. // ------------------------------------------------------------------------ public void setImageHeight(int imageHeight) { this.imageHeight=imageHeight; } // ------------------------------------------------------------------------ // Nastaveni zdrojove pixmapy. // ------------------------------------------------------------------------ public void setSourceImage(int pixelSrc[]) { this.pixelSrc=pixelSrc; } // ------------------------------------------------------------------------ // Nastaveni cilove pixmapy. // ------------------------------------------------------------------------ public void setDestinationImage(int pixelDest[]) { this.pixelDest=pixelDest; } // ------------------------------------------------------------------------ // Ziskani sirky zpracovavanych pixmap. // ------------------------------------------------------------------------ public int getImageWidth() { return imageWidth; } // ------------------------------------------------------------------------ // Ziskani vysky zpracovavanych pixmap. // ------------------------------------------------------------------------ public int getImageHeight() { return imageHeight; } // ------------------------------------------------------------------------ // Ziskani zdrojove pixmapy. // ------------------------------------------------------------------------ public int[] getSourceImage() { return pixelSrc; } // ------------------------------------------------------------------------ // Ziskani cilove pixmapy. // ------------------------------------------------------------------------ public int[] getDestinationImage() { return pixelDest; } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // zadny filtr, pouze kopie zdrojove pixmapy do cilove pixmapy. // ------------------------------------------------------------------------ public void filterNone() { int pos=0; for (int j=0; j<imageHeight; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth; i++) { // pro vsechny pixely na radku pixelDest[pos]=0xffffffff; // provest vymazani pixelu pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 2x2 pixely s vyberem ve tvaru bloku. // ------------------------------------------------------------------------ public void filter2x2smooth() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat for (int j=0; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=4; g/=4; b/=4; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixely s vyberem ve tvaru diamantu. // ------------------------------------------------------------------------ public void filter3x3diamond() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=4; g/=4; b/=4; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixely s vyberem ve tvaru osoveho krize. // ------------------------------------------------------------------------ public void filter3x3cross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixelu s vyberem ve tvaru uhlopricneho krize. // ------------------------------------------------------------------------ public void filter3x3Xcross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth-1]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 3x3 pixelu s blokovym vyberem. // ------------------------------------------------------------------------ public void filter3x3block() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1+imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth-1]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=9; g/=9; b/=9; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru diamantu. // ------------------------------------------------------------------------ public void filter5x5diamond() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth+0]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos- imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=8; g/=8; b/=8; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru osoveho krize. // ------------------------------------------------------------------------ public void filter5x5cross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth+0]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos- imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=9; g/=9; b/=9; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru uhlopricneho krize. // ------------------------------------------------------------------------ public void filter5x5Xcross() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth-2]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=9; g/=9; b/=9; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // rozmazani v bloku 5x5 pixelu s vyberem ve tvaru bloku. // ------------------------------------------------------------------------ public void filter5x5block() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2+2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth-2]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos- imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth-2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+0]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=25; g/=25; b/=25; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // horizontalni filtr rozmazani tri pixelu. // ------------------------------------------------------------------------ public void filter3pixelsH() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=1; for (int j=0; j<imageHeight; j++) { // pro vsechny radky pixmapy for (int i=1; i<imageWidth-1; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-1]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=3; g/=3; b/=3; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // vertikalni filtr rozmazani tri pixelu. // ------------------------------------------------------------------------ public void filter3pixelsV() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=imageWidth; for (int j=1; j<imageHeight-1; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=3; g/=3; b/=3; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // horizontalni filtr rozmazani peti pixelu. // ------------------------------------------------------------------------ public void filter5pixelsH() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2; for (int j=0; j<imageHeight; j++) { // pro vsechny radky pixmapy for (int i=2; i<imageWidth-2; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos-1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+1]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } // ------------------------------------------------------------------------ // Tato metoda provede filtraci pixmapy s filtrem typu: // vertikalni filtr rozmazani peti pixelu. // ------------------------------------------------------------------------ public void filter5pixelsV() { int pos=0; // index do zdrojove a cilove pixmapy int color; // RGBA barvove slozky zakodovane do typu int int r, g, b; // jednotlive rozkodovane barvove slozky filterNone(); // nejprve pixmapy zkopirovat pos=2*imageWidth; for (int j=2; j<imageHeight-2; j++) { // pro vsechny radky pixmapy for (int i=0; i<imageWidth; i++) { // pro vsechny sloupce na radku pixmapy color=pixelSrc[pos-2*imageWidth]; r =(color & 0x00ff0000)>>16; g =(color & 0x0000ff00)>>8; b =(color & 0x000000ff); color=pixelSrc[pos- imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+ imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); color=pixelSrc[pos+2*imageWidth]; r+=(color & 0x00ff0000)>>16; g+=(color & 0x0000ff00)>>8; b+=(color & 0x000000ff); r/=5; g/=5; b/=5; // provest filtraci pixelDest[pos]=(r<<16) | (g<<8) | b | (0xff<<24); pos++; } } } } // ---------------------------------------------------------------------------- // Konec tridy Filter. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s panelem, na kterem se zobrazuje pixmapa o predem danem rozmeru. // ---------------------------------------------------------------------------- class ImagePanel extends Canvas { int width; // rozmery pixmapy int height; public int[] pixels; // pixmapa - zdroj pixelu MemoryImageSource imageSource; // objekt zaobalujici zdroj pixelu Image image; // pixmapa vytvorena nad zdrojem pixelu // ------------------------------------------------------------------------ // V konstruktoru se nastavi velikost panelu a soucasne barva jeho pozadi. // ------------------------------------------------------------------------ public ImagePanel(int width, int height) { pixels=new int[width*height]; for (int j=0; j<height; j++) // pro vsechny radky pixmapy for (int i=0; i<width; i++) // pro vsechny sloupce pixmapy pixels[i+j*width]=0xffffffff; // vyplnit pixmapu i s alfa kanalem imageSource=new MemoryImageSource(width, height, pixels, 0, height); image=createImage(imageSource); // vytvoreni pixmapy this.width=width; // nastaveni velikosti pixmapy this.height=height; this.setBackground(Color.white); // nastaveni vlastnosti panelu this.setSize(width, height); } // ------------------------------------------------------------------------ // Pristup k jednotlivym pixelum pixmapy. // ------------------------------------------------------------------------ public void putpixel(int x, int y, int r, int g, int b) { pixels[x+y*width]=r+(g<<8)+(b<<16)+(255<<24); } // ------------------------------------------------------------------------ // Aplikaci dostupne prekresleni celeho panelu s volbou vymazu stare kresby. // ------------------------------------------------------------------------ public void redraw(boolean clear) { Graphics g=this.getGraphics(); if (clear) // premazat starou kresbu g.clearRect(0, 0, width, height); image.flush(); // prenest pixely do obrazu g.drawImage(image, 0, 0, this); // a vykreslit obraz s pixmapou } // ------------------------------------------------------------------------ // Prekresleni panelu s pixmapou. // ------------------------------------------------------------------------ public void paint(Graphics g) { g.drawImage(image, 0, 0, this); // vykreslit obraz s pixmapou } } // ---------------------------------------------------------------------------- // Konec tridy ImagePanel. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s kodem pro zobrazeni napovedy. // ---------------------------------------------------------------------------- class WindowHelp extends Frame implements ActionListener { static boolean visible=false; // priznak indikujici zobrazeni napovedy // ------------------------------------------------------------------------ // Konstrukce okna s napovedou. // ------------------------------------------------------------------------ public WindowHelp() { TextArea text=new TextArea( "1. choose point shape\n"+ "2. choose seed shape (set of starting points)\n"+ "3. adjust number of generated points in a box\n"+ "4. set filter type\n"+ "5. set box count\n"+ "6. set radius step\n"+ "7. then press the 'Recalc' button\n"+ "8. apply filter with 'Redraw' button" ); visible=true; Button buttonOK=new Button("ok"); Label label=new Label("How to work with this applet:"); buttonOK.addActionListener(this); // po stlaceni tlacitka se ma napoveda zavrit this.setSize(320, 240); // nastaveni velikosti a rozmeru okna this.setLocation(100, 100); this.setTitle("Diffuse 7 - Help"); // zobrazeni titulku this.add("Center", text); // a pridani vsech ovladacich prvku this.add("South", buttonOK); this.add("North", label); this.setVisible(true); } // ------------------------------------------------------------------------ // Reakce na stlaceni tlacitka s textem OK. // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { visible=false; this.dispose(); } } // ---------------------------------------------------------------------------- // Konec tridy WindowHelp. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s kodem pro zobrazeni informaci o aplikaci. // ---------------------------------------------------------------------------- class WindowAbout extends Frame implements ActionListener { static boolean visible=false; // priznak indikujici zobrazeni okna // ------------------------------------------------------------------------ // Konstrukce okna s informaci o aplikaci. // ------------------------------------------------------------------------ public WindowAbout() { TextArea text=new TextArea( "Diffuse 7 demo\n\n"+ "version 1.0\n"+ "Author: Pavel Tisnovsky\n"+ "Date: 2004-07-25\n"+ "http://www.fit.vutbr.cz/~tisnovpa\n" ); visible=true; Button buttonOK=new Button("ok"); Label label=new Label("About Diffuse 7"); buttonOK.addActionListener(this); // po stlaceni tlacitka se ma okno zavrit this.setSize(320, 240); // nastaveni velikosti a rozmeru okna this.setLocation(100, 100); this.setTitle("Diffuse 7 - About"); // zobrazeni titulku this.add("Center", text); // a pridani vsech ovladacich prvku this.add("South", buttonOK); this.add("North", label); this.setVisible(true); } // ------------------------------------------------------------------------ // Reakce na stlaceni tlacitka s textem OK. // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { visible=false; this.dispose(); } } // ---------------------------------------------------------------------------- // Konec tridy WindowAbout. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida s kodem pro zobrazeni informaci o systemu. // ---------------------------------------------------------------------------- class WindowInfo extends Frame implements ActionListener { static boolean visible=false; // priznak indikujici zobrazeni okna // ------------------------------------------------------------------------ // Konstrukce okna s informacemi. // ------------------------------------------------------------------------ public WindowInfo() { Runtime r=Runtime.getRuntime(); // ziskat objekt s informacemi o aplikaci TextArea text=new TextArea(""); text.append("Total memory: "+r.totalMemory()+"\n"); text.append("Free memory: "+r.freeMemory()+"\n"); visible=true; Button buttonOK=new Button("ok"); Label label=new Label("System informations:"); buttonOK.addActionListener(this); // po stlaceni tlacitka se ma okno zavrit this.setSize(320, 240); // nastaveni velikosti a rozmeru okna this.setLocation(100, 100); this.setTitle("Diffuse 7 - Info"); // zobrazeni titulku this.add("Center", text); // a pridani vsech ovladacich prvku this.add("South", buttonOK); this.add("North", label); this.setVisible(true); } // ------------------------------------------------------------------------ // Reakce na stlaceni tlacitka s textem OK. // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { visible=false; this.dispose(); } } // ---------------------------------------------------------------------------- // Konec tridy WindowInfo. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Rozhrani s tvary seminek. // ---------------------------------------------------------------------------- interface SeedShape { int OnePoint= 0, // seminko ve tvaru jednoho bodu TwoPoints= 1, // dva body na usecce ThreePoints= 2, // tri body ve vrcholech trojuhelnika FourPoints= 3, // ctyri body ve vrcholech ctverce ShortCenterLine= 4, // cast usecky CenterLine= 5, // usecka ve spodni casti obrazce Square= 6, // ctverec Border= 7, // ctverec az k okrajum bitmapy SmallCircle= 8, // mala kruznice NormalCircle= 9, // normalni kruznice BigCircle= 10; // vetsi kruznice } // ---------------------------------------------------------------------------- // Konec rozhrani SeedShape. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Rozhrani s tvary bodu. // ---------------------------------------------------------------------------- interface PointShape { int OnePixel= 0, // bod ma tvar jednoho pixelu Cross3x3= 1, // pet pixelu ve tvaru krize XCross3x3= 2, // pet pixelu ve tvaru uhlopricneho krize Diamond3x3= 3, // ctyri pixely ve tvaru diamantu Block3x3= 4, // blok deviti pixelu Cross5x5= 5, // dtto pro okoli 5x5 XCross5x5= 6, Diamond5x5= 7, Block5x5= 8, Horizontal3=9, // tri pixely vedle sebe Horizontal5=10, // pet pixelu vedle sebe Vertical3= 11, // tri pixely pod sebou Vertical5= 12; // pet pixelu pod sebou } // ---------------------------------------------------------------------------- // Konec rozhrani PointShape. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Rozhrani se jmeny filtru. // ---------------------------------------------------------------------------- interface FilterType { int None= 0, // zadny filtr Smooth2x2= 1, // filtr typu 2x2 smooth Diamond3x3= 2, // filtr typu 3x3 diamond Cross3x3= 3, // filtr typu 3x3 cross XCross3x3= 4, // filtr typu 3x3 X cross Block3x3= 5, // filtr typu 3x3 block Diamond5x5= 6, // filtr typu 5x5 diamond Cross5x5= 7, // filtr typu 5x5 cross XCross5x5= 8, // filtr typu 5x5 X cross Block5x5= 9, // filtr typu 5x5 block Horizontal3=10, // filtr typu 3 pixels horizontal Horizontal5=11, // filtr typu 5 pixels horizontal Vertical3= 12, // filtr typu 3 pixels vertical Vertical5= 13; // filtr typu 5 pixels vertical } // ---------------------------------------------------------------------------- // Konec rozhrani FilterType. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // V pripade, ze by bylo nutne tento demonstrani program spustit jako Java ap- // likaci, je mozne odkomentovat metodu "main". V tomto pripade se vsak vytvo- // ri dalsi soubor .class s anonymni tridou Listener. // ---------------------------------------------------------------------------- public class Diffuse7 extends Applet implements Runnable, ActionListener, ItemListener, AdjustmentListener, SeedShape, FilterType, PointShape { static final int ImageWidth=256; // sirka pixmapy s fraktalem static final int ImageHeight=256; // vyska pixmapy s fraktalem static final int DrawingWidth=256; // sirka kresby pouzivane pro konstrukci fraktalu int points=10000; // pocet vsech iteraci int boxCount=100; // pocet boxu int radiusStep=1; // zmena radiusu int pointShape=PointShape.OnePixel;// typ vykreslovanych bodu int seedShape=SeedShape.OnePoint; // tvar seminka int filterType=FilterType.Cross3x3;// typ pouziteho filtru boolean neighboorType=false; // typ okoli pixelu // vytvoreni vsech panelu pouzitych v appletu ImagePanel panelLeft= new ImagePanel(ImageWidth, ImageHeight); ImagePanel panelCenter= new ImagePanel(ImageWidth, ImageHeight); Panel panelUp= new Panel(new GridLayout(2, 4, 5, 5));// horni panel s list-boxy Panel panelDown= new Panel(new GridLayout(2, 3, 5, 5));// dolni panel s posuvniky Panel panelRight= new Panel(new GridLayout(8, 1));// pravy panel s tlacitky // filtr aplikovany na zdrojovou pixmapu, vysledek je v cilove pixmape Filter filter=new Filter(ImageWidth, ImageHeight, panelLeft.pixels, panelCenter.pixels); // objekt, ve kterem je implementovan algoritmus difuze Diffuser diffuser=null; // vytvoreni vsech textovych navesti pouzitych v appletu Label labelPointShape= new Label("Point shape"); Label labelSeedShape= new Label("Seed shape"); Label labelNeighbourHoodType= new Label("Neighbourhood type"); Label labelFilterType= new Label("Filter"); Label labelPointsInBox= new Label("Max. points: "+String.valueOf(points)); Label labelBoxCount= new Label("Box count: "+String.valueOf(boxCount)); Label labelRadiusStep= new Label("Radius step: "+String.valueOf(radiusStep)); // vytvoreni vsech list-boxu pouzitych v appletu Choice choicePointShape= new Choice(); // list-box pro vyber tvaru bodu Choice choiceSeedShape= new Choice(); // list-box pro vyber tvaru seminka Choice choiceNeigbourhoodType= new Choice(); // list-box pro vyber okoli pixelu Choice choiceFilter= new Choice(); // list-box pro vyber aktivniho filtru // vytvoreni vsech tlacitek pouzitych v appletu Button buttonRedraw= new Button("Redraw"); Button buttonRecalc= new Button("Recalc"); Button buttonAbout= new Button("About"); Button buttonInfo= new Button("Info"); Button buttonHelp= new Button("Help"); // vytvoreni vsech slideru pouzitych v appletu Scrollbar scrollBarPoints= new Scrollbar(Scrollbar.HORIZONTAL, points, 1000, 100, 20000+1000); Scrollbar scrollBarBoxCount= new Scrollbar(Scrollbar.HORIZONTAL, boxCount, 20, 50, 270); Scrollbar scrollBarRadiusStep= new Scrollbar(Scrollbar.HORIZONTAL, radiusStep, 1, 1, 21); // ------------------------------------------------------------------------ // Tato metoda provede inicializaci horniho panelu s rolovacimi list-boxy. // Metoda je zavolana behem inicializace aplikace ci appletu. // ------------------------------------------------------------------------ private void initPanelUp() { panelUp.setBackground(Color.white); // nastaveni barvy pozadi panelUp.add(labelPointShape); // pridani vsech textovych navesti panelUp.add(labelSeedShape); // do horniho panelu panelUp.add(labelNeighbourHoodType); panelUp.add(labelFilterType); panelUp.add(choicePointShape); // pridani vsech list-boxu panelUp.add(choiceSeedShape); panelUp.add(choiceNeigbourhoodType); panelUp.add(choiceFilter); // prace s list-boxem pointShape choicePointShape.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu choicePointShape.add("1 pixel"); choicePointShape.add("Cross 3x3 pixels"); choicePointShape.add("X cross 3x3 pixels"); choicePointShape.add("Diamond 3x3 pixels"); choicePointShape.add("Block 3x3 pixels"); choicePointShape.add("Cross 5x5 pixels"); choicePointShape.add("X cross 5x5 pixels"); choicePointShape.add("Diamond 5x5 pixels"); choicePointShape.add("Block 5x5 pixels"); choicePointShape.add("3 pixels horizontal"); choicePointShape.add("5 pixels horizontal"); choicePointShape.add("3 pixels vertical"); choicePointShape.add("5 pixels vertical"); choicePointShape.select(pointShape); // vyber aktivni polozky z list-boxu choicePointShape.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu // prace s list-boxem NeighbourhoodType choiceNeigbourhoodType.setEnabled(true); // naplneni list-boxu s typem okoli pixelu choiceNeigbourhoodType.add("4 pixels"); choiceNeigbourhoodType.add("8 pixels"); choiceNeigbourhoodType.select(0); // vyber aktivni polozky z list-boxu choiceNeigbourhoodType.addItemListener(this);// nastaveni zpracovani udalosti od list-boxu // prace s list-boxem SeedShape choiceSeedShape.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu choiceSeedShape.add("One point"); choiceSeedShape.add("Two points"); choiceSeedShape.add("Three points"); choiceSeedShape.add("Four points"); choiceSeedShape.add("Short center line"); choiceSeedShape.add("Center line"); choiceSeedShape.add("Square"); choiceSeedShape.add("Border size"); choiceSeedShape.add("Small circle"); choiceSeedShape.add("Normal circle"); choiceSeedShape.add("Big circle"); choiceSeedShape.select(seedShape); // vyber aktivni polozky z list-boxu choiceSeedShape.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu // prace s list-boxem Filter choiceFilter.setEnabled(true); // naplneni list-boxu texty a povoleni list-boxu choiceFilter.add("none"); choiceFilter.add("2x2 smooth"); choiceFilter.add("3x3 diamond"); choiceFilter.add("3x3 cross"); choiceFilter.add("3x3 X cross"); choiceFilter.add("3x3 block"); choiceFilter.add("5x5 diamond"); choiceFilter.add("5x5 cross"); choiceFilter.add("5x5 X cross"); choiceFilter.add("5x5 block"); choiceFilter.add("3 pixels horizontal"); choiceFilter.add("5 pixels horizontal"); choiceFilter.add("3 pixels vertical"); choiceFilter.add("5 pixels vertical"); choiceFilter.select(filterType); // vyber aktivni polozky z list-boxu choiceFilter.addItemListener(this); // nastaveni zpracovani udalosti od list-boxu } // ------------------------------------------------------------------------ // Tato metoda provede inicializaci dolniho panelu se slidery. // Metoda je zavolana behem inicializace aplikace ci appletu. // ------------------------------------------------------------------------ private void initPanelDown() { panelDown.setBackground(Color.white); // nastaveni barvy pozadi panelDown.add(labelPointsInBox); // pridani vsech textovych navesti panelDown.add(labelBoxCount); panelDown.add(labelRadiusStep); panelDown.add(scrollBarPoints); // pridani vsech slideru panelDown.add(scrollBarBoxCount); panelDown.add(scrollBarRadiusStep); scrollBarPoints.addAdjustmentListener(this);// nastaveni reakci na udalosti slideru scrollBarBoxCount.addAdjustmentListener(this); scrollBarRadiusStep.addAdjustmentListener(this); } // ------------------------------------------------------------------------ // Tato metoda provede nastaveni praveho panelu s tlacitky (buttony). // Metoda je zavolana behem inicializace aplikace ci appletu. // ------------------------------------------------------------------------ private void initPanelRight() { panelRight.setBackground(Color.white); // nastaveni barvy pozadi panelRight.add(buttonRecalc); // pridani vsech textovych tlacitek panelRight.add(buttonRedraw); panelRight.add(new Label("")); // volna polozka pro oddeleni tlacitek panelRight.add(buttonAbout); panelRight.add(buttonInfo); panelRight.add(buttonHelp); buttonRedraw.addActionListener(this); // nastaveni reakce na udalosti od tlacitek buttonRecalc.addActionListener(this); buttonAbout.addActionListener(this); buttonInfo.addActionListener(this); buttonHelp.addActionListener(this); } // ------------------------------------------------------------------------ // Tato metoda provede inicializaci appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void init() { this.setBackground(Color.white); // nastaveni barvy pozadi setLayout(new BorderLayout(5,5)); // nastaveni layoutu aplikace initPanelUp(); // nastavit horni panel initPanelDown(); // nastavit dolni panel initPanelRight(); // nastavit pravy panel add("North", panelUp); // pridat horni panel do plochy aplikace add("South", panelDown); // pridat dolni panel do plochy aplikace add("East", panelRight); // pridat pravy panel do plochy aplikace add("Center", panelCenter); // pridat centralni panel do plochy aplikace add("West", panelLeft); } // ------------------------------------------------------------------------ // Tato metoda se zavola pri destrukci appletu. // Metoda je volana z virtualniho stroje Javy (JVM) // ------------------------------------------------------------------------ public void destroy() { remove(panelLeft); remove(panelRight); // zrusit pravy panel remove(panelUp); // zrusit horni panel remove(panelDown); // zrusit dolni panel remove(panelCenter); // zrusit centralni panel } // ------------------------------------------------------------------------ // Tato metoda se zavola vzdy pri nastartovani appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void start() { } // ------------------------------------------------------------------------ // Tato metoda se zavola pri kazdem zastaveni appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void stop() { } // ------------------------------------------------------------------------ // Tato metoda se zavola pri nastartovani appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void run() { repaint(); // prvotni vykresleni plochy appletu } // ------------------------------------------------------------------------ // Tato metoda se zavola vzdy, kdyz je nutno prekreslit plochu appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void update(Graphics g) { paint(g); // povolit prekresleni appletu } // ------------------------------------------------------------------------ // Tato metoda se zavola kdyz je potreba prekreslit applet. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void paint(Graphics g) { } // ------------------------------------------------------------------------ // Nastaveni vnitrnich okraju v okne appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public Insets getInsets() { return new Insets(5, 5, 5, 5); } // ------------------------------------------------------------------------ // Tato metoda je zavolana v pripade, ze je stlaceno nektere tlacitko // umistene na plose appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void actionPerformed(ActionEvent e) { Object o=e.getSource(); // ktere tlacitko je stlaceno? if (o==buttonRedraw) { // ma se pouze prekreslit fraktal panelLeft.redraw(false); applyFilter(); panelCenter.redraw(false); } if (o==buttonRecalc) { // prepocitani celeho fraktalu recalcFractal(); } if (o==buttonAbout) { // text s informacemi o autorech if (!WindowAbout.visible) { WindowAbout window=new WindowAbout(); } } if (o==buttonHelp) { // text s napovedou if (!WindowHelp.visible) { WindowHelp window=new WindowHelp(); } } if (o==buttonInfo) { // text s informacemi o aplikaci if (!WindowInfo.visible) { WindowInfo window=new WindowInfo(); } } } // ------------------------------------------------------------------------ // Tato metoda je zavolana v pripade, ze je vybran prvek z list-boxu // umisteneho na plose appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void itemStateChanged(ItemEvent e) { Object o=e.getSource(); // ziskat informace, ktery list-box je zmenen if (o==choicePointShape) { pointShape=choicePointShape.getSelectedIndex(); } if (o==choiceSeedShape) { seedShape=choiceSeedShape.getSelectedIndex(); } if (o==choiceFilter) { // uzivatel zmenil filtr aplikovany na obrazek filterType=choiceFilter.getSelectedIndex();// ziskat index vybraneho filtru applyFilter(); panelCenter.redraw(false); } if (o==choiceNeigbourhoodType) { // uzivatel zmenil typ okoli pixelu neighboorType=(choiceNeigbourhoodType.getSelectedIndex()==1); } } // ------------------------------------------------------------------------ // Tato metoda je zavolana v pripade, ze uzivatel zmenil polohu nektereho // posuvniku (slideru) umisteneho na plose appletu. // Metoda je volana z virtualniho stroje Javy (JVM). // ------------------------------------------------------------------------ public void adjustmentValueChanged(AdjustmentEvent e) { Object o=e.getSource(); // ziskat slider, ktery byl zmenen if (o==scrollBarPoints) { // zmena poctu bodu generovanych v boxu points=scrollBarPoints.getValue(); // ziskat pocet bodu labelPointsInBox.setText("Max. points: "+String.valueOf(points)); } if (o==scrollBarBoxCount) { // zmena poctu boxu boxCount=scrollBarBoxCount.getValue(); // ziskat novou hodnotu labelBoxCount.setText("Box count: "+String.valueOf(boxCount)); } if (o==scrollBarRadiusStep) { // zmena radiusu radiusStep=scrollBarRadiusStep.getValue();// ziskat novou hodnotu labelRadiusStep.setText("Radius step: "+String.valueOf(radiusStep)); } } // ------------------------------------------------------------------------ // Tato metoda zmeni aktualni filtr. // ------------------------------------------------------------------------ public void applyFilter() { switch (filterType) { case FilterType.None: filter.filterNone(); break; // zadny filtr case FilterType.Smooth2x2: filter.filter2x2smooth(); break; // filtr typu 2x2 smooth case FilterType.Diamond3x3: filter.filter3x3diamond(); break; // filtr typu 3x3 diamond case FilterType.Cross3x3: filter.filter3x3cross(); break; // filtr typu 3x3 cross case FilterType.XCross3x3: filter.filter3x3Xcross(); break; // filtr typu 3x3 X cross case FilterType.Block3x3: filter.filter3x3block(); break; // filtr typu 3x3 block case FilterType.Diamond5x5: filter.filter5x5diamond(); break; // filtr typu 5x5 diamond case FilterType.Cross5x5: filter.filter5x5cross(); break; // filtr typu 5x5 cross case FilterType.XCross5x5: filter.filter5x5Xcross(); break; // filtr typu 5x5 X cross case FilterType.Block5x5: filter.filter5x5block(); break; // filtr typu 5x5 block case FilterType.Horizontal3:filter.filter3pixelsH(); break; // filtr typu 3 pixels horizontal case FilterType.Horizontal5:filter.filter5pixelsH(); break; // filtr typu 5 pixels horizontal case FilterType.Vertical3: filter.filter3pixelsV(); break; // filtr typu 3 pixels vertical case FilterType.Vertical5: filter.filter5pixelsV(); break; // filtr typu 5 pixels vertical default: break; // tato volba by nemela nikdy nastat } } // ------------------------------------------------------------------------ // Tato metoda provede prepocet fraktalu. // ------------------------------------------------------------------------ private void recalcFractal() { if (diffuser!=null) { if (diffuser.isAlive()) return; } diffuser=new Diffuser(); // vytvorit diffuser diffuser.setPixels(panelLeft.pixels); // nastavit jeho parametry diffuser.setSize(ImageWidth, ImageHeight); diffuser.setMaxPoints(points); diffuser.setBoxCount(boxCount); diffuser.setRadiusStep(radiusStep); diffuser.setPointShape(pointShape); diffuser.setSeedShape(seedShape); diffuser.setNeighbourhoodType(neighboorType); diffuser.setObject(this); diffuser.start(); // a spustit ho } /* // ----------------------------------------------------------------------- // Metoda main, ktera neni v appletu vyuzita. // Muze se definovat v pripade, ze se ma vytvorit samostatne spustitelna // aplikace interpretovana virtualnim strojem jazyja Java, nikoli applet. // V tomto pripade se vsak vytvori dalsi soubor .class s anonymni tridou // se jmenem Listener. // ----------------------------------------------------------------------- public static void main(String[] args) { Frame frame=new Frame("Diffuse7"); Applet applet=new Diffuse7(); frame.add(applet); applet.init(); frame.setSize(640, 480); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); } */ } // ---------------------------------------------------------------------------- // Konec tridy Diffuse7. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Trida, ve krere je implementovan algoritmus simulace difuze. // ---------------------------------------------------------------------------- class Diffuser extends Thread { Frame frame=null; // okno pro vypis prubehu prace Label label=null; // do tohoto labelu se bude provadet vypis int pixelSrc[]; // pixmapa pro vykreslovani int width; // velikost pixmapy int height; int boxCount; // pocet boxu int radiusStep; // zmena radiusu int maxPoints; // max. pocet bodu int pointShape; // typ vykreslovych bodu int seedShape; // tvar seminka int boxesInRow; // pocet boxu generovanych v jednom radku boolean neighboorType; // typ okoli pixelu boolean pixels[][]; // pomocna mrizka, ve ktere se bude generovat boolean yCoordinateType; // zpusob vypoctu pocatecni y-ove souradnice Diffuse7 object; // objekt s panely, do kterych se kresli // ----------------------------------------------------------------------- // Konstruktor, ve kterem se nastavi vhodne implicitni hodnoty. // ----------------------------------------------------------------------- public Diffuser() { pixelSrc=null; width=height=100; maxPoints=10000; pointShape=seedShape=0; boxCount=100; radiusStep=1; neighboorType=false; pixels=null; yCoordinateType=true; } // ----------------------------------------------------------------------- // Nastaveni pixmapy, do ktere se bude provadet vykreslovani // ----------------------------------------------------------------------- public void setPixels(int pixels[]) { pixelSrc=pixels; } // ----------------------------------------------------------------------- // Nastaveni rozmeru generovane pixmapy. // ----------------------------------------------------------------------- public void setSize(int width, int height) { this.width=width; this.height=height; } // ----------------------------------------------------------------------- // Nastaveni maximalniho poctu bodu v pixmape. // ----------------------------------------------------------------------- public void setMaxPoints(int maxPoints) { this.maxPoints=maxPoints; } // ----------------------------------------------------------------------- // Zmena poctu boxu. // ----------------------------------------------------------------------- public void setBoxCount(int boxCount) { this.boxCount=boxCount; } // ----------------------------------------------------------------------- // Zmena delty radiusu kruznice. // ----------------------------------------------------------------------- public void setRadiusStep(int radiusStep) { this.radiusStep=radiusStep; } // ----------------------------------------------------------------------- // Nastaveni typu okoli pixelu, na kterem se provadi testy. // ----------------------------------------------------------------------- public void setNeighbourhoodType(boolean neighboorType) { this.neighboorType=neighboorType; } // ----------------------------------------------------------------------- // Nastaveni tvaru, ktery se bude ukladat do pracovni bitmapy. // ----------------------------------------------------------------------- public void setPointShape(int pointShape) { this.pointShape=pointShape; } // ----------------------------------------------------------------------- // Nastaveni seminka - pocatecnich bodu fraktalniho obrazce. // ----------------------------------------------------------------------- public void setSeedShape(int seedShape) { this.seedShape=seedShape; } // ----------------------------------------------------------------------- // Predani reference hlavniho GUI objektu. // ----------------------------------------------------------------------- public void setObject(Diffuse7 o) { object=o; } // ----------------------------------------------------------------------- // Nastaveni zpusobu vypoctu y-ove pocatecni souradnice. // ----------------------------------------------------------------------- public void setYCoordinateType(boolean yCoordinate) { this.yCoordinateType=yCoordinate; } // ----------------------------------------------------------------------- // Vytvoreni a zobrazeni pomocneho okna, ve kterem se zobrazuje prubeh prace. // ----------------------------------------------------------------------- private void prepareGUI() { frame=new Frame("Computing diffuse"); label=new Label("Points:"); frame.add(label); label.setAlignment(Label.CENTER); // vlastnosti napisu label.setVisible(true); frame.setSize(200, 100); // vlastnosti okna frame.setVisible(true); } // ----------------------------------------------------------------------- // Tato metoda se zavola po dokonceni generovani fraktalu. // ----------------------------------------------------------------------- private void finishGUI() { label.setText("Filtering bitmaps"); object.panelLeft.redraw(false); object.applyFilter(); // aplikace filtru na bitmapu object.panelCenter.redraw(false); frame.setVisible(false); // a zruseni pomocneho okna frame.dispose(); } // ----------------------------------------------------------------------- // Vytvoreni a inicializace pomocneho pole - plosne rastrove bitove mrizky, // do ktere se bude obrazec difuze generovat. // ----------------------------------------------------------------------- private void initBitmap() { pixels=new boolean[height][width]; for (int j=0; j<height; j++) { for (int i=0; i<width; i++) { pixels[j][i]=false; // vsechny pixely nastavit } // na stejnou hodnotu false } } // ----------------------------------------------------------------------- // Kopie dat z pomocne bitmapy (pomocne rastrove bitove mrizky) do pixmapy, // ktera se bude zobrazovat v hlavnim okne aplikace ci appletu. // ----------------------------------------------------------------------- private void copyBitmapToPixmap() { int pos=0; for (int j=0; j<height; j++) { for (int i=0; i<width; i++) { // pixel je bud cerny nebo bily pixelSrc[pos]=pixels[j][i] ? // podle pravdivostni hodnoty ulozene v poli pixelu 0xff000000: // nastavit cerny pixel nebo 0xffffffff; // nastavit bily pixel pos++; // index do cilove pixmapy } // (ktera je typu truecolor) } } // ----------------------------------------------------------------------- // Tato metoda provadi inicializaci seminka - pocatecnich bodu ve vznika- // jicim fraktalnim objektu, ke kterym se v dalsim prubehu simulace difuze // pridavaji dalsi body. // ----------------------------------------------------------------------- private void initSeed() { int wh=width/2; // horizontalni stred pracovni bitmapy int hh=height/2; // vertikalni stred pracovni bitmapy int wh1=1*width/3; // prvni horizontalni tretina pracovni bitmapy int wh2=2*width/3; // druha horizontalni tretina pracovni bitmapy int hh1=1*height/3; // prvni vertikalni tretina pracovni bitmapy int hh2=2*height/3; // druha vertikalni tretina pracovni bitmapy switch (seedShape) { case SeedShape.OnePoint: // generuje se pouze jeden bod pixels[hh][wh]=true; // uprostred pracovni bitmapy break; case SeedShape.TwoPoints: // generuji se dva symetricky postavene body pixels[hh][wh1]=true; pixels[hh][wh2]=true; break; case SeedShape.ThreePoints: // generuji se tri symetricky postavene body pixels[hh][wh]=true; pixels[hh][wh1]=true; pixels[hh][wh2]=true; break; case SeedShape.FourPoints: // generuji se ctyri pixels[hh][width/5]=true; // symetricky postavene body pixels[hh][2*width/5]=true; pixels[hh][3*width/5]=true; pixels[hh][4*width/5]=true; break; case SeedShape.ShortCenterLine: // generuje se kontinualni for (int i=wh1; i<=wh2; i++) // usecka uprostred bitmapy pixels[hh][i]=true; break; case SeedShape.CenterLine: // generuje se usecka ve stredu bitmapy for (int i=0; i<width; i++) pixels[hh][i]=true; break; case SeedShape.Square: // generuje se ctverec ve stredu bitmapy for (int i=wh1; i<=wh2; i++) { pixels[hh1][i]=true; pixels[hh2][i]=true; } for (int i=hh1; i<=hh2; i++) { pixels[i][wh1]=true; pixels[i][wh2]=true; } break; case SeedShape.Border: // generuje se okraj z radky pixelu for (int i=0; i<width; i++) { // usporadanych okolo cele bitmapy pixels[0][i]=true; pixels[height-1][i]=true; } for (int i=0; i<height; i++) { pixels[i][0]=true; pixels[i][width-1]=true; } break; case SeedShape.SmallCircle: // generuje se mala kruznice uprostred bitmapy { double r=wh/4.0; for (int i=0; i<1000; i++) { double x=wh+r*Math.cos((double)i); double y=hh+r*Math.sin((double)i); pixels[(int)y][(int)x]=true; } } break; case SeedShape.NormalCircle: // generuje se kruznice uprostred bitmapy { double r=wh/2.0; for (int i=0; i<1000; i++) { double x=wh+r*Math.cos((double)i); double y=hh+r*Math.sin((double)i); pixels[(int)y][(int)x]=true; } } break; case SeedShape.BigCircle: // generuje se velka kruznice uprostred bitmapy { double r=wh-9.0; for (int i=0; i<1000; i++) { double x=wh+r*Math.cos((double)i); double y=hh+r*Math.sin((double)i); pixels[(int)y][(int)x]=true; } } break; default: pixels[hh][wh]=true; break; } } // ----------------------------------------------------------------------- // Tato metoda vrati pravdivostni hodnotu true v pripade, ze se v okoli // zadaneho pixelu vyskytuje jiny pixel, jez nalezi do vytvareneho // fraktalniho (difuzniho) objektu. V opacnem pripade se z funkce vrati // pravdivostni hodnota false. Typ okoli je predan v parametru type. // ----------------------------------------------------------------------- private boolean neighboor(boolean type, int i, int j) { // kontrola mezi pro pristup do pole if (i<2 || j<2 || i>width-2 || j>height-2) return false; return type ? pixels[j-1][i-1] | // osmiokoli pixelu pixels[j-1][i] | pixels[j-1][i+1] | pixels[j][i-1] | pixels[j][i+1] | pixels[j+1][i-1] | pixels[j+1][i] | pixels[j+1][i+1] : pixels[j-1][i] | // ctyrokoli pixelu pixels[j][i-1] | pixels[j][i+1] | pixels[j+1][i] ; } // ----------------------------------------------------------------------- // Vykresleni bodu, tj. jednoho pixelu ci nekolika pixelu, do temporalni // bitmapy (plosne rastrove bitove mrizky) podle uzivatelem predem // zvoleneho tvaru bodu. Tvar bodu je specifikovan v promenne pointShape. // ----------------------------------------------------------------------- private void putPoint(int x, int y) { if (x<3) x=3; // zabranit zapisum if (x>=width-3) x=width-4; // mimo pole (bitmapu) if (y<3) y=3; if (y>=height-3) y=height-3; if (pointShape!=PointShape.Diamond3x3 && // krome dvou specialnich tvaru pointShape!=PointShape.Diamond5x5) { pixels[y][x]=true; // vykreslit prostredni pixel } if (pointShape==PointShape.Cross3x3 || pointShape==PointShape.Diamond3x3 || pointShape==PointShape.Block3x3 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Block5x5 || pointShape==PointShape.Horizontal3 || pointShape==PointShape.Horizontal5) { pixels[y][x-1]=true; // nastavit pixel nalevo pixels[y][x+1]=true; // a pixel napravo } // od prostredniho pixelu if (pointShape==PointShape.Horizontal5 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Diamond5x5 || pointShape==PointShape.Block5x5) { pixels[y][x-2]=true; // nastavit druhy pixel nalevo pixels[y][x+2]=true; // a druhy pixel napravo } // od prostredniho pixelu if (pointShape==PointShape.Cross3x3 || pointShape==PointShape.Diamond3x3 || pointShape==PointShape.Block3x3 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Block5x5 || pointShape==PointShape.Vertical3 || pointShape==PointShape.Vertical5) { pixels[y-1][x]=true; // nastavit pixel nahore pixels[y+1][x]=true; // a pixel dole } // od prostredniho pixelu if (pointShape==PointShape.Vertical5 || pointShape==PointShape.Cross5x5 || pointShape==PointShape.Diamond5x5 || pointShape==PointShape.Block5x5) { pixels[y-1][x]=true; // nastavit druhy pixel nahore pixels[y+1][x]=true; // a druhy pixel dole } // od prostredniho pixelu if (pointShape==PointShape.XCross3x3 || pointShape==PointShape.Block3x3 || pointShape==PointShape.XCross5x5 || pointShape==PointShape.Diamond5x5 || pointShape==PointShape.Block5x5) { pixels[y-1][x-1]=true; // nastavit ctyri diagonalni pixely pixels[y+1][x-1]=true; pixels[y-1][x+1]=true; pixels[y+1][x+1]=true; } if (pointShape==PointShape.XCross5x5 || pointShape==PointShape.Block5x5) { pixels[y-2][x-2]=true; // nastavit ctyri diagonalni pixely pixels[y+2][x-2]=true; // ve vzdalenosti 2 pixels[y-2][x+2]=true; // od prostredniho pixelu pixels[y+2][x+2]=true; } if (pointShape==PointShape.Block5x5) { pixels[y-2][x-1]=true; // nastavit zbyvajicich osm pixelu pixels[y+2][x-1]=true; // v bloku 5x5 pixelu pixels[y-2][x+1]=true; pixels[y+2][x+1]=true; pixels[y-1][x-2]=true; pixels[y+1][x-2]=true; pixels[y-1][x+2]=true; pixels[y+1][x+2]=true; } } // ----------------------------------------------------------------------- // Aplikace algoritmu difuze, jez je zalozen na postupnem pohybu bodu // v pracovni bitmape (binarni rastrove mrizce). Pocatecni pozice bodu // lezi na kruznici, ktera se pri behu algoritmu plynule zvetsuje od // stredu vznikajiciho obrazce difuze az do okraju vytvarene bitmapy. // ----------------------------------------------------------------------- private void applyDiffuse() { final int CounterThreshold=200; // pocet bodu pro provedeni vypisu // do GUI okna appletu ci aplikace int counter=0; // pocitadlo vytvorenych bodu int points=0; // pocitadlo vsech bodu int dist; // vzdalenost od stredu obrazce float alpha; // uhel vytvoreneho bodu od x-ove osy int x, y; // souradnice generovanych bodu int box; // pocitadla smycek int originX=width>>1; // souradnice stredu pracovni bitmapy int originY=height>>1; int radius; // maximalni povoleny polomer kruznice boolean looking; if (originX<originY) // vypocet maximalniho povoleneho radius=originX; // polomeru kruznice z rozmeru else // pracovni bitmapy radius=originY; putPoint(originX, originY); // vytvorit bod ve stredu obrazce // (tento bod je vzdy soucasti seminka) // hlavni programova smycka, jez obstarava zmenu velikosti kruznice, na ktere se for (dist=0; dist<radius-1; dist+=radiusStep) { // vytvari pocatecni pozice bodu box=0; // vnitrni smycka pro vygenerovani zadaneho poctu oblasti while (box<boxCount) { // uhel odchylky mereny od horizontalni osy alpha=(float)(Math.random()*2.0*Math.PI); // souradnice leveho horniho rohu oblasti // prevedeneho na pixely x=(int)(originX+dist*Math.cos(alpha)); y=(int)(originY+dist*Math.sin(alpha)); looking=true; // nastavit priznak hledani bodu // vnitrni smycka pro nalezeni mista pripojeni pixelu k obrazci difuze do { x+=Math.random()*3.0-1; // posun pixelu v plose y+=Math.random()*3.0-1; // na jeho osmiokoli if (x<1) x++; // kontrola, zda pixel if (x>width-2) x--; // lezi uvnitr povolene if (y<1) y++; // oblasti v bitmape if (y>height-2) y--; // pokud se pixel dotkl stavajiciho objektu if (neighboor(neighboorType, x, y)){ putPoint(x, y); // je k nemu pripojen looking=false; // hledani lze ukoncit points++; // zvysit pocitadlo vsech pripojenych bodu box++; } // po dosazeni dostatecneho poctu pripojenych pixelu counter++; // prubezny vypis prace programu if (counter==CounterThreshold) { label.setText("Points: " // do GUI okna appletu ci aplikace +String.valueOf(points) +" dist: " +String.valueOf(dist)); counter=0; } } while (looking); // interni smycku ukoncit az po pripojeni } // pixelu k obrazci difuze } // konec hlavni programove smycky } // ----------------------------------------------------------------------- // Funkce, ktera rozbehne cele vypocetni vlakno. // ----------------------------------------------------------------------- public void run() { prepareGUI(); // vytvoreni vsech GUI prvku label.setText("Initializing"); initBitmap(); // inicializace bitmapy initSeed(); // inicializace seminka applyDiffuse(); // aplikace algoritmu difuze label.setText("Finishing"); copyBitmapToPixmap(); // kopie pracovni bitmapy do vysledne pixmapy finishGUI(); // fitrace a zavreni pomocneho okna } } // ---------------------------------------------------------------------------- // Konec tridy Diffuser. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // finito // ----------------------------------------------------------------------------