Clasa java.awt.image

Pachetul java.awt.image conține 3 interfețe cu funcții specifice: ImageConsumer, ImageObserver, ImageProducer. ImageProducer este interfața care produce date de tip imagine pentru tipul de date Image. Fiecare imagine conține o instanțiere a ImageProducer, care este folosită la reconstrucția imaginii ori de câte ori este solicitat acest lucru. Interfața ImageConsumer este interesată de datele produse prin interfața ImageProducer. Când un consumator este asociat unui producător de imagini, acesta din urmă va trimite toate datele despre imagine folosind metoda call. ImageObserver este o interfață ce primește informații despre o imagine în timp ce este creată.

Cred că este utillă o sumară trecere în revistă a claselor ce alcătuiesc clasa java.awt.image. Prezentarea este făcută la nivel de introducere, urmând ca cei interesați să încerce să implementeze facilitățile oferite de fiecare clasă în parte.

ColorModel este clasa ce încapsulează metode pentru descompunerea unui pixel în componentele sale RGB (roșu, verde, albastru). Constructorul poate fi aplelat, specificând un număr de biți alocați pentru un pixel. Este o clasă utilă în prelucrarea digitală a imaginilor color.

IndexColorModel este o clasă ce descompune pixelii în componentele RGB pentru pixelii care dețin informația de culoare, ca indecși într-o hartă a culorilor. De notat că majoritatea metodelor acestei clase sunt finale (adică nu mai pot fi schimbate prin redefinirea într-o clasă ce extinde clasa IndexColorModel)

DirectColorModel este o clasă ce descompune pixelii în componentele RGB pentru pixelii care au componentele de culoare încapsulate direct în biții pixelului însuși. Acest model este similar cu modelul X11 TrueColor.

ImageFilter este clasa ce implementează un filtru, pentru diferitele metode ce sunt folosite pentru a transmite date de la un ImageProducer spre un ImageConsumer. Se poate folosi și un Null Filter ce lasă imaginea neafectată în procesul de mai sus. Pentru a produce versiuni filtrate ale imaginii, această clasă se va folosi în conjuncție cu un obiect de tip FilteredImageSource.

CropImageFilter este o clasă ce extinde clasa de mai sus și este folosită pentru a extrage o regiune dreptunghiulară, dată dintr-un obiect de tip Image și pentru a furniza sursa pentru un nou obiect de tip Image, ce va conține doar regiunea decupată. Va fi folosită în conjuncție cu un obiect de tip FilteredImageSource pentru a crea versiuni decupate ale imaginii existente.

FilteredImageSource este o implementare a interfeței ImageProducer. Această clasă preia o imagine și un obiect, de tip filtru, și le folosește pentru a produce o versiune filtrată a imaginii originale. De exemplu, codul pentru schimbarea componentelor roșu și albastru dintr-o imagine este:

Image src = getImage("doc: ///demo/images/duke/T1.gif");
 	  ImageFilter colorfilter = new RedBlueSwapFilter();
      Image img = createImage(new FilteredImageSource
            (src.getSource(),colorfilter));  	 

MemoryImageSource este o implementare a clasei ImageProducer, care folosește un vector pentru a determina valorile pixelilor pentru o imagine dată. Un exemplu de creare a unei imagini cu un efect de degrade, de la negru la albastru pe axa Ox și de la negru la roșu pe axa Oy:

int w = 100; 
   int h = 100; 
   int pix[] = new int[w*h]; 
   int index = 0; 
   for (int y = 0; y < h; y++) {
       int red = (y * 255) / (h - 1); 
       for (int x = 0; x < w; x++) { 
          int blue = (x * 255) / (w - 1); 
          pix[index++] = (255 << 24) | (red << 16) | blue; 
          } 
   } 
   Image img = createImage(new MemoryImageSource(w, h, pix, 0, w));

PixelGrabber este o clasă ce implementează un obiect de tip ImageConsumer, care poate fi atașat de către un ImageProducer sau de Image, pentru a trimite un set de pixeli în acea imagine. De exemplu:

int[] pixels = new int[w * h]; 
PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w); 
try { 
>   pg.grabPixels();
   } 
catch (InterruptedException e) {
   System.err.println("interrupted waiting for pixels!"); 
   return;
   } 
if ((pg.status() & ImageObserver.ABORT) != 0) {
   System.err.println("image fetch aborted or errored");
   return;
   }
for (int j = 0; j < h; j++) {
   for (int i = 0; i < w; i++) {
      handlesinglepixel(x+i, y+j, pixels[j * w + i]);
      }
   }
}

RGBImageFilter furnizează un mod ușor de a crea un ImageFilter, care modifică pixeli unei imagini în modul implicit RGB ColorModel. Se utilizează în conjuncție cu FilteredImageSource, pentru a produce versiuni filtrate ale imaginilor existente. Exemplu:

class RedBlueSwapFilter extends RGBImageFilter {
 public RedBlueSwapFilter(){
 // The filter's operation does not depend on the 
 // pixel's location, so IndexColorModels can be
 // filtered directly. canFilterIndexColorModel = true;
 }
 public int filterRGB(int x, int y, int rgb) {
   return ((rgb & 0xff00ff00) | ((rgb & 0xff0000) >> 16) | 
       ((rgb & 0xff) << 16));
   }
 }

În figura „Codul sursă la aplicației" este prezentată ierarhia acestor clase. În paranteze, acolo unde există, este scrisă și clasa pe care o implementează fiecare dintre clasele din java.awt.image.

Arhitectura aplicației

Aplicația este de tip Applet (deci se încarcă dintr-o pagină de HTML) și implementează interfața Runnable (deci folosește Thread-urile). Aplicația va afișa o imagine preluată din același catalog unde rulează programul și memorată într-un fișier de tip .jpg sau .gif. Numele imaginii va fi preluat într-un string din fișierul HTML, asociat cu appletul.

Interfața cu utilizatorul este alcătuită din 3 butoane (init, crop, nou). La apăsarea butonului init, se afișează imaginea preluată de program, prin intermediul fisierului HTML, asociat appletului. Prin acționarea butonului crop, se permite selectarea zonei care se dorește decupată din imaginea inițială. Imaginea obținută din această decupare va fi afișată în locul vechii imagini, prin apăsarea butonului nou. O serie de mesaje ajutătoare pot fi citite pe consola Navigatorului făcând aplicația foarte prietenoasă.

Thread-ul, folosit în program, asigură citirea permanentă a stării celor 3 butoane. Prin folosirea clasei MediaTracker, se evită clipirea ecranului în timpul afișării imaginii. Cu metoda addImage se introduce imaginea care va fi afișată. Metoda waitForID blochează afișarea imaginii, până ce aceasta este complet încărcată în memorie. Alte comentarii, referitoare la utilizarea fiecărei metode, sunt prezentate chiar în codul sursă al programului.

Considerații personale

Multe alte aplicații pot fi realizate cu ajutorul clasei java.awt.image. O posibilitate interesantă este dată de prelucrarea imaginilor cu ajutorul filtrelor. Efecte întâlnite până acum în programele specializate (Adobe Photoshop, Corel Draw, ș.a.) pot fi generate acum prin setul de metode și clase deținut de java.awt.image. Nu depinde decât de ingeniozitatea programatorului, pentru a asigura o interfață cât mai atractivă acestor facilități și, eventual, de a integra toate aceste programe într-o singură aplicație integrată.

Imaginați-vă efectul unei astel de aplicații, apelate dintr-o pagină de Web. Utilizatorul, comod instalat în fața propriului computer, apelează la serviciile de vânzare ale unei companii de automobile. Prin aplicarea diferitelor filtre, își alege nuanța de culoare preferată dintr-o sumedenie de nuanțe generate prin intermediul limbajului Java. Prin selecții ale mouse-ului, poate decupa și vizualiza la scară mărită anumite părți ale mașinii mult visate. Poate deschide portiere, geamuri, poate simula mersul mașinii, toate acestea printr-un motor Java de animație. La sfârșit de tot, după ce și-a configurat mașina după dorință, completează un formular generat de o aplicație Java și, prin clasa java.net, îl trimite (neapărat criptat) prin rețea.


BYTE România - septembrie 1997


(C) Copyright Computer Press Agora