Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Modelul de mod imediat Java 2D

java


Modelul de mod imediat Java 2D

Pentru a diminua unele dintre restrictiile modelului de procesare AWT original si pentru a furniza un nivel mai ridicat de abstractizare, a fost elaborata o noua specificatie denumita Java 2D API. Acest nou API extinde capacitatile AWT pentru grafica bidimensionala si pentru procesarea de imagini. În realitate, pachetul Java 2D este unificat cu AWT si este o componenta a platformei Java 2 Standard Edition.



Imaginile în Java 2D API sunt compuse din doua componente principale:

Date imagine brute care reprezinta pixeli

Informatia necesara pentru interpretarea pixelilor

În ceea ce priveste procesarea de imagini, Java 2D API retine câteva elemente din modelul AWT producator/consumator, dar adauga conceptul de date imagine persistente bazate pe memorie, set extensibil de filtre imagine 2D, o varietate mare de formate de imagine si modele de culoare si o reprezentare mai sofisticata a dispozitivelor de iesire. Java 2D introduce notiunea de reprezentare a imaginilor independenta de rezolutie prin introducerea interfetelor Renderable si Rendered, permitându-se imaginilor sa fie trase printr-un lant de operatii filtru, cu rezolutia imaginii selectata prin contextul reprezentarii.

În Figura 7.1 este prezentat modelul de gestiune generala a imaginilor din Java 2D, care este controlat de catre clasa BufferedImage.


Un obiect de tip BufferedImage poate fi creat direct în memorie si utilizat pentru a pastra si manipula date imagine obtinute de la un fisier sau de la un URL. Un BufferedImage poate fi afisat folosind orice obiect Graphics2D ca dispozitiv de afisare, sau reprezentat spre orice alta destinatie folosind un context Graphics2D adecvat. Un obiect de tip BufferedImage contine doua alte obiecte: un Raster si un ColorModel.

Clasa Raster asigura gestiunea datelor imagine. Acesta reprezinta o arie dreptunghiulara dintr-o imagine care stocheaza datele imagine în memorie si de asemenea un mecanism pentru crearea a mai multor sub-imagini dintr-un singur bufer de date imagine. Aceasta clasa asigura metode pentru accesul la pixeli specifici dintr-o imagine. Un obiect Raster contine doua alte obiecte, un DataBuffer si un SampleModel.

Clasa DataBuffer pastreaza datele pixelului în memorie. Clasa SampleModel interpreteaza datele din bufer si furnizeaza pixeli individuali sau regiuni de pixeli dreptunghiulare.

Regulile pentru interpretarea pixelilor sunt încapsulate într-un obiect ColorModel, de exemplu daca valorile trebuie interpretate în mod direct sau ca culori indexate. Astfel pentru ca un pixel sa fie afisat, acesta trebuie sa fie împerecheat cu un model de culoare.

Pachetul java.awt.image contine câteva implementari ale clasei ColorModel, incluzând acele pentru reprezentari împachetate si pe componente ale pixelului. Tot acest pachet furnizeaza clase suplimentare care definesc operatii de filtrare asupra unor obiecte BufferedImage si Raster. Fiecare operatie de procesare este concretizata printr-o clasa care implementeaza interfata BufferedImageOp, sau interfata RasterOp, sau amândoua. Clasa de operatii defineste metodele de filtrare prin care se efectueaza manipularea imaginii. În Figura 7.2. este ilustrat modelul de baza pentru procesarile de imagini din Java 2D API.


Operatiile suportate includ:

Transformare affine

Scalare de amplitudine

Modificare cu tabele de cautare (lookup table)

Combinare liniara a benzilor

Conversie de culori

Convolutie

Elemente data sunt primitive tip utilizate ca unitati de stocare a datelor imagine. Elementele data sunt membrii individuali ai unei arii DataBuffer. Configuratia elementelor în buferul de date este independenta de interpretarea datelor ca pixeli de catre obiectul SampleModel al imaginii.

Esantioanele sunt membrii distincti de pixeli ai unei imagini. Un obiect SampleModel asigura un mecanism pentru convertirea elementelor din DataBuffer în pixeli si esantioanele sale. Esantioanele unui pixel pot sa reprezinte valori de baza într-un model de culoare particular, de exemplu, un pixel dintr-un model de culoare RGB este compus din trei esantioane: red, green si blue.

Componentele sunt valori ale pixelilor independente de interpretarea culorilor. Distinctia dintre componenta si esantion este folositoare pentru IndexColorModel, unde componentele pixelului sunt indexate într-un LookupTable.

O banda este o componenta a spatiului de culoare a unei imagini. De exemplu, componentele de rosu, verde si albastru reprezinta benzile dintr-o imagine RGB. Datele pixelilor pot fi stocate în mai multe moduri, iar Java 2D suporta doua dintre acestea: organizare pe benzi si arie regulata de pixeli.

Stocarea pe benzi a pixelilor determina ca un pixel sa fie format dintr-o data esantion de la aceeasi pozitie în fiecare banda. Stocarea pixelilor într-o arie organizeaza datele imagine în pixeli, astfel avem o singura arie continând toti pixelii, iar benzile sunt constituite dintr-un set de esantioane la aceeasi pozitie de index pentru fiecare pixel.

Un obiect ColorSpace încapsuleaza regulile care guverneaza modul în care un set de masurari corespund unei culori anume. Implementarile clasei ColorSpace din pachetul java.awt.color reprezinta cele mai utilizate spatii de culoare, incluzând RGB sau scala de gri. Un spatiu de culoare reprezinta niste reguli pentru modul cum vor fi interpretate valorile culorilor.

Separatia spatiului de culoare de modelul de culoare asigura o flexibilitate sporita la reprezentarea si conversia culorilor dintr-un anumit spatiu al culorii în altul.

7.3.1. Clasa BufferedImage

Clasa BufferedImage este clasa principala care suporta procesarea de imagini în modul imediat. Aceasta clasa gestioneaza imaginea în memorie asigurând metode de stocare, interpretare si reprezentare a datelor pixelilor spre un context Graphics sau Graphics2D. Pentru a crea un obiect BufferedImage, se apeleaza metoda Component.createImage. Aceasta returneaza un obiect de tip BufferedImage a carui caracteristici de reprezentare se potrivesc cu cele ale componentei folosite pentru creare. Imaginea creata este opaca si are culorile de suprafata si fundal ale obiectului Component, cu posibilitatea de modificare a transparentei. Acest lucru este exemplificat pe sectiunea de cod urmatoare (Exemplul 7.2).

Exemplul 7.2. Utilizarea clasei BufferedImage

BufferedImage offImg;

public Graphics2D

createMyG2D(Graphics g)

if (offImg != null)

// sterge componenta

g2.clearRect(0, 0, width, height);

return g2;


Clasa BufferedImage poate fi folosita la pregatirea elementelor grafice în afara ecranului si apoi afisarea lor pe ecran. Aceasta tehnica este folositoare atunci când un element grafic este utilizat în mod repetat.

Facilitatile pachetului java.awt permit folosirea buferelor de pregatire în afara ecranului, astfel modificarea unei imagini se face în acelasi mod ca si cum ea ar fi afisata într-o fereastra. Toate facilitatile de reprezentare Java 2D pot fi aplicate atunci când se lucreaza cu imagini în afara ecranului.

Cea mai simpla metoda de a crea o imagine, care poate fi folosita ca si un bufer în afara ecranului, este prin apelul metodei Component.createImage.

Clasa BufferedImage suporta câteva tipuri de imagine predefinite:

TYPE_3BYTE_BGR - imagine cu componente de culoare RGB pe 8 biti, corespunzatoare modelului de culoare RGB din Windows, cu culorile Blue, Green si Red stocate pe 3 bytes.

TYPE_4BYTE_ABGR - imagine cu componente de culoare RGBA pe 8 biti, cu culorile Blue, Green si Red stocate pe 3 bytes si un byte pentru canalul alfa.

TYPE_4BYTE_ABGR_PRE - imagine cu componente de culoare RGBA pe 8 biti cu culorile Blue, Green si Red stocate pe 3 bytes si un byte pentru alfa

TYPE_BYTE_BINARY - imagine opaca pe 1, 2 sau 4 biti

TYPE_BYTE_GRAY - imagine scala de gri pe un unsigned byte, neindexata.

TYPE_BYTE_INDEXED - imagine pe un byte indexata.

TYPE_CUSTOM - imagine nerecunoscuta, de tip utilizator.

TYPE_INT_ARGB_PRE - imagine cu componente de culoare RGBA pe 8 biti compusa din pixeli integer.

TYPE_INT_ARGB - imagine cu componente de culoare RGBA pe 8 biti compusa din pixeli integer.

TYPE_INT_BGR - imagine cu componente de culoare RGBA pe 8 biti, corespunzator pentru modelele de culoare din Windows sau Solaris, cu culorile Blue, Green si Red împachetate în pixeli integer.

TYPE_INT_RGB - reprezinta o imagine cu componente de culoare RGB pe 8 biti împachetate în pixeli integer.

TYPE_USHORT_555_RGB - imagine cu componente de culoare 5-5-5 RGB (5-biti Red, 5-biti Green, 5-biti Blue) fara canal alfa.

TYPE_USHORT_565_RGB - imagine cu componente de culoare 5-6-5 RGB (5-biti Red, 6-biti Green, 5-biti Blue) fara canal alfa.

TYPE_INT_GRAY - imagine în scala de gri stocata pe tipul unsignrd short, neindexata.

Pentru reprezentarea într-un obiect de tip BufferedImage, se apeleaza metoda BufferedImage.createGraphics, care returneaza un obiect Graphics2D. Cu acest obiect se pot apela toate metodele pentru reprezentarea primitivelor grafice, sau reprezentarea altor imagini în imagine. În fragmentul de cod urmator (Exemplul 7.3.) se ilustreaza utilizarea buferarii în afara ecranului:

Exemplul 7.3. Exemplu de utilizare a buferarii în afara ecranului

public void update(Graphics g)

// sterge suprafata care a fost desenata anterior

big.setColor(Color.white);

big.clearRect(0, 0, area.width, area.height);

// Deseneaza si umple un nou dreptunghi în bufer.

big.setPaint(drept1);

big.draw(rect);

big.setPaint(drept2);

big.fill(rect);

// Deseneaza un buffered image pe ecran.

g2.drawImage(bi, 0, 0, this);


7.3.1.1. Manipularea datelor de tipul BufferedImage

În afara de desenarea direct într-un obiect BufferedImage, se pot accesa si manipula datele pixelilor dintr-o imagine în mai multe moduri. Acest lucru este util daca se implementeaza interfata de filtrare BufferedImageOp.

Se poate utiliza metodele BufferedImage.setRGB pentru a modifica în mod direct valoarea unui pixel sau a unei arii de pixeli la o valoare RGB specificata. De asemenea se poate manipula datele pixelului prin intermediul unui obiect WritableRaster asociat cu un BufferedImage.

7.3.1.2. Filtrarea si reprezentarea unui BufferedImage

Operatia de filtrare se poate aplica la un BufferedImage utilizând un obiect care implementeaza interfata BufferedImageOp.

Pentru a reprezenta o imagine buferata într-un context specific se apeleaza una dintre metodele drawImage din contextul obiectului Graphics. De exemplu, atunci când se reprezinta folosind metoda Component.paint, se apeleaza drawImage asupra obiectului de afisare grafica transmis la metoda (vezi Exemplul 7.4).

Exemplul 7.4. Reprezentarea unui BufferedImage

public void paint(Graphics g)


7.3.2. Gestiunea si manipularea obiectelor rastru

Un obiect BufferedImage utilizeaza un obiect Raster pentru gestiunea ariilor dreptunghiulare de date pixel. Clasa Raster contine câmpuri pentru coordonatele sistem a imaginii - latime, înaltime si origine. Un obiect Raster utilizeaza doua obiecte pentru gestiunea datelor pixelilor, un obiect DataBuffer si un obiect SampleModel. Obiectul DataBuffer stocheaza datele pixelilor pentru rastru, iar obiectul SampleModel furnizeaza interpretarea datelor pixelilor din obiectul DataBuffer.

De cele mai multe ori, nu este nevoie sa cream un obiect Raster în mod direct deoarece este furnizat odata cu crearea obiectelor BufferedImage. Cu toate acestea, unul dintre constructorii BufferedImage permite crearea unui Raster prin trecerea printr-un obiect WritableRaster.

Clasa Raster furnizeaza un numar de metode statice pentru crearea de obiecte Raster cu obiectele de tip DataBuffer si SampleModel specificate ca parametrii. Aceste metode sunt utile atunci când se implementeaza clase de tipul RasterOp pentru filtrare.

Clasa Raster încorporeaza conceptul de raster parinte si raster copil. Acest lucru poate sa îmbunatateasca eficienta de stocare prin permiterea construirii oricarui numar de imagini buferate din acelasi parinte. Parintele si copii sai reprezinta acelasi bufer de date, iar fiecare copil are un deplasament si limite pentru asi putea identifica pozitia imaginii din bufer. Un copil îsi identifica apartenenta prin intermediul metodei getParent.

Pentru a crea un subrastru, se apeleaza metoda Raster.createSubRaster. Daca se creeaza un subrastru, se poate identifica aria parintelui care-l acopera si deplasamentul de la originea parintelui.

Clasa Raster defineste mai multe metode de acces la pixeli si la datele pixelilor. Acest lucru este util atunci când se implementeaza interfata RasterOp, care asigura filtrare la nivel de rastru si manipulare a datelor imagine sau atunci când se implementeaza orice metoda care are nevoie sa execute manipulari de pixeli de nivel inferior.

Metodele Raster.getPixel permit preluarea unui pixel individual care este returnat ca esantion individual dintr-o arie. Metodele Raster.getDataElements returneaza o portiune specificata a imaginii neinterpretata din DataBuffer. Metoda Raster.getSample returneaza esantioane cu un pixel individual. Metoda getSamples returneaza o banda pentru o regiune specificata dintr-o imagine. Buferul de date si modelul de esantioane poate fi de asemenea accesat prin intermediul variabilelor instanta a clasei Raster. Aceste obiecte asigura mijloace suplimentare pentru accesarea si interpretarea datelor pixel a unui obiect Raster.

Subclasa WritableRaster asigura metode pentru modificarea datelor pixel si a esantioanelor. Obiectul Raster asociat cu un obiect BufferedImage formeaza un obiect WritableRaster, asigurând acces total la manipularea datelor pixel.

7.3.3. Date imagine si bufere de date

Obiectele de tip DataBuffer apartinând unui Raster reprezinta o arie de date imagine. La crearea unui Raster în mod direct sau prin intermediul constructorilor BufferedImage, se poate specifica latimea si înaltimea, împreuna cu un obiect SampleModel pentru datele imagine. Aceste informatii sunt folosite la crearea unui DataBuffer cu tipul de data si dimensiune corespunzatoare.

Exista patru subclase a DataBuffer, fiecare reprezentând un tip diferit de date element:

DataBufferByte - valori pe 8 biti

DataBufferInt - valori pe 32 biti

DataBufferShort - valori pe 16 biti

DataBufferUShort - reprezinta valori de tip short fara semn.

Elementele sunt membrii discreti ai unei arii din buferul de date, iar componentele sau esantioanele sunt valori discrete care împreuna formeaza un pixel. Exista diverse alocari între un tip de element particular din DataBuffer si un tip particular de pixel reprezentat de un obiect SampleModel. Aceasta alocare este implementata de diversele subclase ale clasei SampleModel si furnizeaza o modalitate de extragere de pixeli dintr-un DataBuffer specific.

Datele imagine pot fi accesate în mod direct într-un DataBuffer, dar este mai usor si mai convenabil sa se acceseze prin intermediul metodelor din clasele Raster si WritableRaster.

Clasele pentru reprezentarea datelor imagine sunt prezentate în Tabelul 7.3.

Clasa

Descrierea

DataBuffer

Acopera unul sau mai multe arii de date. Fiecare arie de date ne este referentiata ca si un grup.

Raster

Reprezinta o arie dreptunghiulara de pixeli si furnizeaza metode pentru obtinerea de date imagine.

SampleModel

Extrage esantioane de pixeli din imagini.

WriteableRaster

Furnizeaza metode pentru stocarea datelor imagine si mosteneste metode pentru obtinerea datelor imagine de la parintele ei, clasa Raster.

Tabelul 7.3. Clasele utilizate de Java 2D pentru

reprezentarea datelor imagine

7.3.4. Extragerea datelor pixel dintr-un obiect SampleModel

Clasa abstracta SampleModel defineste metode pentru extragerea esantioanelor dintr-o imagine fara a cunoaste modalitatea în care datele imagine sunt stocate. Clasa contine câmpuri pentru monitorizarea înaltimii si latimii datelor imagine din obiectul DataBuffer asociat si pentru descrierea unui numar de benzi si a tipului de data pentru acel bufer. Metodele SampleModel asigura date imagine ca si colectie de pixeli, fiecare pixel fiind format dintr-un numar de esantioane sau componente.

Pachetul java.awt.image furnizeaza cinci tipuri de modele de esantioane:

ComponentSampleModel - utilizat pentru extragerea pixelilor din imaginile care stocheaza esantioanele în arii de elemente data separate al unui segment dintr-un DataBuffer.

BandedSampleModel - utilizat pentru extragerea pixelilor din imaginile care stocheaza fiecare esantion într-un element data separat cu benzile stocate într-o secventa de elemente data.

PixelInterleavedSampleModel - utilizat pentru extragerea pixelilor din imaginile care stocheaza fiecare esantion într-un element data separat cu pixeli stocati într-o secventa de elemente data.

MultiPixelPackedSampleModel - utilizat pentru extragerea pixelilor din imaginile cu o singura banda care stocheaza mai multi pixeli cu un singur esantion într-un singur element data.

SinglePixelPackedSampleModel - utilizat pentru extragerea pixelilor din imaginile care stocheaza date esantion pentru un singur pixel într-o singura arie de elemente data din primul segment al unui DataBuffer.

Datele pixel oferite de SampleModel pot fi corelate direct cu un mod de reprezentare a datelor culoare dintr-un model de culoare particular, în functie de datele sursa. De exemplu, în datele imagine ale unei fotografii esantioanele pot sa reprezinte date RGB. În datele imagine de la un dispozitiv de prelucrare a imaginilor medicale esantioanele pot sa reprezinte tipuri diferite de date ca de exemplu temperatura sau densitatea oaselor.

Exista trei categorii de metode pentru accesarea datelor imagine. Metodele getPixel returneaza un pixel întreg ca si o arie cu o singura valoare pentru fiecare esantion. Metodele getDataElement asigura accesul la datele brute, neinterpretate stocate în DataBuffer. Metodele getSample asigura accesul la componentele pixelului pentru o banda specifica.

7.3.5. Modele si date culoare

Ca o completare la obiectul Raster în gestiunea datelor imagine, clasa BufferedImage include un obiect ColorModel pentru interpretarea acestor date ca si valori de culoare pixel. Clasa abstracta ColorModel defineste metode pentru transformarea datelor pixel dintr-o imagine într-o valoare culoare din spatiul de culoare ColorSpace asociat.

Pachetul java.awt.image furnizeaza patru tipuri de modele de culoare:

PackedColorModel - un model abstract care reprezinta valorile pixelilor care au componente de culoare continute direct în bitii unui pixel de tip integer. Clasa DirectColorModel este o subclasa a PackedColorModel.

DirectColorModel - un model de culoare care reprezinta valorile pixelilor care au componente de culoare RGB continute direct în bitii pixelului însusi.

ComponentColorModel - un model de culoare care poate manipula un spatiu de culoare ColorSpace arbitrar si o arie de componente de culoare care sa se potriveasca spatiului de culoare.

IndexColorModel - un model de culoare care reprezinta valorile pixelilor care sunt indici într-o harta de culori fixa din spatiul de culoare RGB.

SampleModel furnizeaza modelul de culoare ColorModel bazându-se pe datele din DataBuffer, apoi ColorModel interpreteaza datele ca si culoare.

O tabela de cautare (lookup table) contine date pentru una sau mai multe canale sau componente imagine. De exemplu, arii separate pentru R, G si B. Pachetul java.awt.image defineste doua tipuri de tabele de cautare care extinde clasa abstracta LookupTable, unul care contine date byte si unul care contine date short si anume ByteLookupTable si ShortLookupData.

7.3.6. Procesare si îmbunatatire de imagini în Java 2D

Pachetul java.awt.image furnizeaza o pereche de interfete care definesc operatii asupra obiectelor BufferedImage si Raster: BufferedImageOp si RasterOp.

Cele mai importante clase care implementeaza aceste interfete sunt: AffineTransformOp, BandCombineOp, ConvolveOp, LookupOp, RescaleOp. Aceste clase pot fi utilizate pentru transformari geometrice, blur, sharpen, îmbunatatire de contrast, binarizare si modificarea culorilor imaginilor.

Fragmentul de cod urmator (Exemplul 7.5.) exemplifica o operatie de detectie de margini aplicata asupra unei imagini folosind o operatie de convolutie:

Exemplul 7.5. Detectie de margini folosind Java 2D

float[] elements = ;

BufferedImage bimg = new

BufferedImage(bw,bh,BufferedImage.TYPE_INT_RGB);

Kernel kernel = new Kernel(3, 3, elements);

ConvolveOp cop = new ConvolveOp(kernel,

ConvolveOp.EDGE_NO_OP, null);

cop.filter(bi,bimg);


Urmatorul fragment de cod (Exemplul 7.6.) demonstreaza o operatie de manipulare a imaginilor folosind tabele de cautare (lookup table):

Exemplul 7.6. Manipulare de tip lookup table

byte reverse[] = new byte[256];

for (int j=0; j<200; j++)

ByteLookupTable blut=new ByteLookupTable(0, reverse);

LookupOp lop = new LookupOp(blut, null);

lop.filter(bi,bimg);

O operatie de rescalare a unei imagini este prezentata în fragmentul de cod care urmeaza (Exemplul 7.7.):

Exemplul 7.7. Operatie de rescalare

RescaleOp rop = new RescaleOp(1.5f, 1.0f, null);

rop.filter(bi,bimg);

Urmatorul fragment de cod (Exemplul 7.8.) ilustreaza modul de utilizare a uneia dintre clasele de procesare a imaginilor, ConvolveOp. În acest exemplu fiecare pixel din imaginea sursa este mediat în mod egal cu cei opt pixeli înconjuratori.

Exemplul 7.8. Utilizarea clasei ConvolveOp

float weight = 1.0f/9.0f;

float[] elements = new float[9]; // creaza o arie 2D

// umple aria cu 9 elemente egale

for (i = 0; i < 9; i++)

// utilizeaza aria de elemente ca si argument la crearea unui Kernel

// (nucleu de convolutie)

private Kernel myKernel = new Kernel(3, 3, elements);

public ConvolveOp simpleBlur = new ConvolveOp(myKernel);

// sourceImage si destImage sunt instante a BufferedImage

simpleBlur.filter(sourceImage, destImage) // aplica blur

Variabila simpleBlur din exemplul anterior contine o noua instanta a ConvolveOp care implementeaza o operatie blur asupra unui BufferedImage sau a unui Raster. Presupunând ca sourceImage si destImage sunt doua instante ale BufferedImage, atunci când este apelata metoda filter, care este metoda principala a clasei ConvolveOp. Aceasta metoda aloca valori pentru fiecare pixel din imaginea destinatie prin medierea pixelului corespunzator din imaginea sursa cu cei opt pixeli înconjuratori.

Prin modificarea nucleului de convolutie se poate executa alte tipuri de convolutii, cum ar fi blurring (Gaussian blur, radial blur, motion blur), sharpening, operatii de netezire, etc.

Urmatorul fragment de cod (Exemplul 7.9.) ilustreaza sharpening folosind operatia de convolutie:

Exemplul 7.9. Operatie sharpening utilizând convolutia

float[] elements = ;

Kernel kernel = new Kernel(3,3,elements);

ConvolveOp cop = new ConvolveOp(kernel,

ConvolveOp.EDGE_NO_OP, null);

cop.filter(bi,bimg);

7.3.7. Independenta de reprezentare

Independenta reprezentarii reprezinta abilitatea de a descrie o imagine asa cum dorim noi sa apara, independent de orice parametru specific ei, cum ar fi rezolutia, dimensiunea fizica, tipul dispozitivului de iesire, calitatea culorilor, calitatea tonala si viteza de reprezentare.

Pentru o descriere a unei imagini independenta de reprezentare sunt necesare doua elemente principale:

O sursa care nu este reprezentata, numita si sursa independenta de rezolutie. Pentru o imagine statica, aceasta reprezinta conceptual, aria de captura a unei camere ideale antrenata asupra unei scene reale, aceasta lipsindu-i orice dimensiuni logice. Camera ideala are o lentila ideala care are posibilitatea de zooming infinita. Imaginea se poate considera ca este proiectata pe orice suprafata (dispozitiv de afisare), are dimensiuni, are un raport de aspect nativ (acela a dispozitivului de captura) si poate sa aiba proprietati care pot fi interogate.

Operatori pentru descrierea modului de modificare a caracterului unei imagini, independent de destinatia finala.

Sursa nereprezentata si operatorii specifica caracterul vizual al imaginii pe care ar trebui sa-l aiba atunci când este reprezentata. Aceasta specificatie poate apoi fi asociata cu orice dispozitiv, dimensiune a dispozitivului de afisare sau calitate a reprezentarii.

Arhitectura Java AWT API integreaza un model de independenta a reprezentarii în paralel cu un model dependent de dispozitiv. Partea de independenta a reprezentarii a arhitecturii este un superset al modelului traditional de procesare dependenta de dispozitiv si nu este un înlocuitor pentru acesta.

Arhitectura Java AWT suporta adaptare dependenta de context, lucru care este potrivit pentru surse aflate în retea. Adaptarea dependenta de context este un mecanism prin care calitatea optima a unei imagini este garantata în orice context.

Java AWT este o arhitectura sincrona. Acest lucru are câteva avantaje, cum ar fi un model de programare simplificat si controale explicite asupra tipului si ordinii rezultatelor, dar are si câteva dezavantaje si anume faptul ca nu este potrivit notiunii de reprezentare progresiva sau resurse disponibile în retea.

7.3.8. Straturi de reprezentare

Arhitectura Java AWT API furnizeaza doua straturi integrate de prelucrare a imaginilor: stratul Renderable si stratul Rendered.

Stratul Renderable este un strat independent de reprezentare. Stratul Renderable furnizeaza surse de imagini care pot fi optimal reutilizate de mai multe ori în contexte diferite, cum ar fi afisarea pe ecran sau imprimarea. Stratul ofera operatori de procesare de imagini care accepta parametrii independenti de reprezentare. Acesti parametri pot fi legati sub forma de lanturi. Stratul este în esenta sincron, în sensul ca "trage" imaginea prin lant oricând o reprezentare (de exemplu spre un dispozitiv de afisare sau un fisier) este solicitata. O solicitare se face la destinatia (sink) a lantului si este transmisa pe lant în sus spre sursa. Asemenea cereri sunt specifice de context (de exemplu specific dispozitivului) si lantul se adapteaza la acest context. Doar datele necesare pentru context sunt produse.

Sursele imagine si operatorii din stratul paralel Rendered sunt specifice de context. Un obiect RenderedImage este o imagine care a fost reprezentata pentru a satisface nevoile unui context. Operatorii din stratul Rendered pot fi de asemenea legati împreuna pentru a forma lanturi. Acestia primesc parametrii dependenti de context. Ca si stratul Renderable, stratul Rendered implementeaza un model sincron de tragere.

Structural, stratul Renderable este subtil, el nu se ocupa cu procesarea pixelilor; mai degraba uzeaza de obiecte operator din stratul Rendered. Acest lucru este posibil deoarece clasele operatorilor din stratul Rendered pot sa implementeze interfata ContextualRenderedImageFactory, care le permite sa se adapteze la diferite contexte. Deoarece operatorii din stratul Renderable implementeaza aceasta interfata, acestia gazduiesc în întregime operatiile specifice. Toata inteligenta necesara pentru functionarea celor doua straturi, Renderable si Rendered sunt tinute într-o singura clasa. Acest lucru simplifica munca de a scrie noi operatori si de a face controlabila arhitectura de extensii.

În Figura 7.3. se ilustreaza un lant Renderable. Lantul are atasat o destinatie (un obiect Graphics2D), dar nici un pixel nu circula prin lant deocamdata.


Stratul Renderable are marele avantaj ca simplifica în mare masura munca de procesare de imagini. De exemplu, un lant de operatori Renderable ramân editabili, parametrii folositi pentru constructia lantului pot fi modificati în mod repetitiv. Acest lucru nu va face sa se înceapa calcularea vreo unui pixel, în schimb pixelii sunt calculati doar atunci când este nevoie, reprezentarea fiind obtinuta de la RenderableImage cu transmiterea definita de contextele de reprezentare.

7.3.9. Context de reprezentare

Stratul Renderable permite constructia unui lant de operatori RenderableImageOps conectati la o sursa RenderableImage. Capatul acestui lant reprezinta o noua sursa RenderableImage. Efectul este ca RenderableImageOps trebuie sa implementeze aceeasi interfata ca si sursele (RenderableImage). Unei astfel de surse i se poate cere sa furnizeze diverse obiecte RenderedImage specifice unui context corespunzator. Dimensiunea necesara în pixeli pentru RenderedImage în spatiul dispozitivului trebuie specificata. Aceasta informatie este furnizata sub forma unei transformari din spatiul utilizator a sursei Renderable spre spatiul dispozitivului dorit.

Alte informatii pot fi date sursei sau lantului pentru a-l ajuta sa functioneze în mod optimal pentru un anume context, de exemplu o preferinta pentru viteza în detrimentul calitatii imaginii. Asemenea informatii se furnizeaza sub forma unui tabel extensibil de indicii.

Arhitectura defineste acesti parametri colectivi ca si context de reprezentare. Parametrii sunt gazduiti de o clasa RenderContext, care formeaza o legatura fundamentala între straturile Renderable si Rendered. O sursa RenderableImage si un RenderContext, produc ca rezultat o reprezentare specifica, sau altfel spus un RenderedImage. Acest lucru este efectuat de lantul Renderable instantiind un lant de obiecte de strat Rendered. Într-un lant de obiecte RenderedImages corespunzatoare unui context specific, obiectul RenderedImage din capat este returnat la utilizator.

7.3.10. Clasele Renderable si Rendered

Stratul Renderable ofera avantajul independentei de reprezentare, eliminând nevoia de a lucra în mod direct cu pixeli, simplificând foarte mult manipularea imaginilor. Cu toate acestea, în multe cazuri este necesar sa se lucreze direct cu pixeli si în acest caz se va folosi stratul Rendered.

7.3.10.1. Stratul Renderable

Stratul Renderable este definit de catre interfata RenderableImage. Orice clasa care implementeaza aceasta interfata este o imagine sursa Renderable si este de asteptat sa se adapteze la contextul de reprezentare RenderContext. Obiectele de tip RenderContext sunt referentiate printr-un sistem de coordonate definite de utilizator. Una din functiile principale ale clasei RenderContext este sa defineasca alocarea spatiului utilizator si spatiul specific dispozitivului pentru o reprezentare dorita.

Un lant în acest strat reprezinta un lant de obiecte RenderableImage, mai precis este un lant de obiecte RenderableImageOp (clasa care implementeaza interfata RenderableImage).

Clasa RenderableImageOp preia functionalitatea unei operatii specifice prin intermediul unui parametru furnizat la momentul instantierii. Acest parametru este numele unei clase care implementeaza interfata ContextualRenderedImageFactory. Fiecare instantiere a RenderableImageOp deriva din functionalitatiile specifice claselor specificate prin nume. În acest sens, stratul Renderable este puternic dependent de stratul Rendered.

Clasele si interfetele utilizate de stratul Renderable sunt prezentate în Tabelul 7.4.

Clasa/Interfata

Descrierea

RenderableImage

O interfata comuna pentru imagini independente de reprezentare

ContextualRenderedImage-Factory

Furnizeaza o interfata pentru functionalitate care poate sa difere între instante diferite de RenderableImageOp.

ParameterBlock

Încapsuleaza toate informatiile despre sursele si parametrii necesari de catre RenderableImageOp si alte clase viitoare care manipuleaza lanturi de operatori de procesare.

RenderableImageOp

Se ocupa de aspectele Renderable a unei operatii cu ajutorul unei instante asociate de ContextualRenderedImageFactory (CRIF).

RenderableImageProducer

O clasa adaptoare care implementeaza ImageProducer si permite producerea asincrona a unui RenderableImage.

RenderContext

Încapsuleaza informatia necesara pentru a produce o reprezentare specifica dintr-un RenderableImage.

Tabelul 7.4. Clasele si interfetele utilizate de stratul Renderable

Un alt bloc implicat în constructia unui RenderableImageOp este ParameterBlock. Clasa ParameterBlock gazduieste sursele pentru operatie si parametrii sau alte obiecte pe care acel operator le poate cere. Parametrii sunt versiuni independente de reprezentare ai parametrilor care controleaza operatorul.

Lantul Renderable este construit prin instantierea fiecarui obiect succesiv de tipul RenderableImageOp, fiind transmis în ultimul obiect RenderableImage ca si sursa în obiectul ParameterBlock. Acestui lant i se poate cere sa furnizeze un numar de reprezentari spre spatii dispozitiv specifice prin intermediul metodei getImage.

Acest lant, odata construit ramâne editabil. Parametrii pentru operatiile specifice din lant si structura propriuzisa a lantului se poate schimba. Acest lucru se poate realiza prin apelul metodei setParameterBlock, modificând parametrii de control sau/si sursele. Aceste modificari afecteaza viitoarele obiecte RenderedImage derivate din punctele din lant care se gasesc în zona inferioara zonei unde sa facut modificarile. Obiectele RenderedImage care sunt obtinute mai devreme din lantul Renderable sunt fixe si complet independente de lantul din care au fost derivate.

7.3.10.2. Stratul Rendered

Stratul Rendered a fost conceput sa functioneze în cooperare cu stratul Renderable. Stratul Renderable include surse si operatii pentru reprezentarea specifica unui dispozitiv a imaginilor sau a reprezentarilor. Stratul Rendered este definit de interfata RenderedImage. Aceasta interfata este implementata de clasa BufferedImage.

Operatorii din acest strat sunt obiecte RenderedImage care preiau alte obiecte RenderedImage ca sursa. Lanturile pot fi construite în aceeasi masura ca si la stratul Renderable. O secventa de obiecte RenderedImage este instantiata, fiecare preluând ultimul obiect RenderedImage ca si sursa.

În Figura 7.4., atunci când utilizatorul invoca metoda Graphics-2D.drawImage, un context de reprezentare este construit si utilizat pentru a apela metoda getImage de la operatorul Renderable. Un operator Rendered, pentru a face de fapt o procesare a pixelilor este construit si atasat la sursa si la destinatia operatorului Renderable si îi este furnizata o clona a blocului de parametri a operatorului Renderable. Pixelii vor "curge" prin operatorul Rendered la obiectul Graphics2D. Lantul operatorului Renderable ramâne disponibil pentru a produce mai multe reprezentari oricând metoda getImage este apelata.


În Tabelul 7.5. sunt prezentate clasele si interfetele utilizate de stratul Rendered.

Clasa/Interfata

Descriere

RenderedImage

O interfata comuna pentru obiecte care contin sau pot produce date imagine sub forma de obiecte Raster.

BufferedImage

O subclasa care descrie un obiect Image cu un bufer de date imagine accesibil.

WritableRenderedImage

O interfata comuna pentru obiecte care contin sau pot produce date imagine care pot fi modificate sau/si suprascrise.

Tabelul 7.5. Clasele si interfetele din stratul Rendered


Document Info


Accesari: 1575
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )