Hem E-böcker Specialeffekter och spelutveckling i Java Hur man hanterar pixels 

Specialeffekter och spelutveckling i Java(TM) - Hur man hanterar pixels 

av Anibal Wainstein

7.0 Hur man hanterar pixels

Äntligen är vi redo för att ge oss in på bildbehandlingsområdet. Det är bildbehandling realtid som ger Java applets möjligheten att bli avancerade specialeffekter såsom bildtoningar, explosioner, 3D-miljöer m.m. Med realtid menas att effekten eller animationen räknas ut innan varje bildruta visas. Detta kräver förstås att man har en någorlunda snabb dator för att det skall gå snabbt. Normalt så räcker en Pentium 100 väl för att köra den här typen av specialeffekter. Det finns två sätt att göra bildbehandling i Java, den som vi kommer att använda är samma teknik som använts i flera år av appletföretag som Demicron och Anfy Java (jag använder det också för de flesta av mina egna applets). Huvudverktygen för den här tekniken är klasserna MemoryImageSource och PixelGrabber. Den andra tekniken, att använda Java's filterklasser, är för långsam och ineffektiv för att vara till nytta när man gör specialeffekter i realtid. Filterklasserna kommer jag därför inte att nämna, förresten har vi inte gått igenom objektorientering ännu.

PROBLEM PÅ MACINTOSH! Om du använder en Macintosh för att läsa det här kapitlet så försäkra dig om att du använder Internet Explorer som webbläsare. Netscape's Java VM är för buggad för att köra den här typen av Java applets (den har alltid varit det). I Netscape 6.0 för Macintosh skall det gå att byta till en annan Java motor. Byt i så fall till Apple's egen Java motor (Macintosh Runtime for Java), den ger dessutom din webbläsare en kapacitet som matchar Netscape och Internet Explorer i PC Windows-miljö. Internet Explorer's Java motor är slöare.

PROBLEM PÅ PC! Om du använder Netscape version 3.0 för Windows så byt till en senare version. Netscape version 3.0 har en minnesbug som gör att createImage() kombinerat med MemoryImageSource klassen leder till minnesläckor. Byt till Netscape version 3.01 eller senare. Ibland kan en upplösning på 32 bitar i Windows leda till konstiga buggar i nya webläsare, detta händer i Internet Explorer (versioner 4.0 till 5.0) och Netscape (versioner 4.0 till 4.5). Använd 16 miljoner färger istället (24 bitars upplösning), slutresultatet blir detsamma i Java applets. Jag rekommenderar att du använder Netscape 3.01 när du programmerar Java applets, den är normen för den perfekta Java-webbläsaren, även om den är mycket slöare än de nyare läsarna. Den närmaste i perfektion är Internet Explorer 4.1.

 

7.0.1 Vad innehåller ett pixelvärde?

I avsnitt 2.0.1 så gick vi igenom hur man blandar till färger och hur RGB fungerar. Som jag har sagt tidigare så består appletskärmen av pixlar. Dessa pixlar ska man kunna manipulera. Ett pixelvärde är ett int-värde som består av fyra bytes. Tre av dem är RGB-komponenterna som vi redan känner till men den fjärde byten är den s.k. alfakanalen. Alfakanalen används inom grafikprogrammering för att indikera hur transparent en pixel skall vara. En delvis transparent pixel kommer att låta en del av bakgrunden lysa igenom. T.ex. om du skall göra en animation av ett spöke, så kan det vara bra att ha 50% transparens på spökets bild, så att det blir en mer realistiskt effekt. I Java 1.02 så kan man bara ha 100% transparens (pixeln är osynlig), eller 0% transparens (pixeln är solid). Men delvis transparens kan simuleras genom färgblandning. Senare webbläsare stöder delvis transparens på alfakanalen. För er som jobbar med HTML, kan det vara lättare att förstå om jag säger att i transparenta GIF89 bilder så är värdet för alfa-kanalen "255" i det synliga området, och "0" i det osynliga området av bilden. Låt oss titta närmare på int-värdet:

 
FF FF FF FF
Alfa Röd Grön Blå


En 32 bitars int-värde representerar ett pixelvärde som innehåller 8 hexadecimala tal och fyra färgkomponenter. Varje komponent i färgvärdet består alltså av två hexadecimala tal.

 

Tabellen ovan representerar en pixel. Du kanske undrar vad "FF" är för något. Det är det hexadecimala motsvarigheten av 255, som är maxvärdet för en byte. En hexadecimalt tal har basen 16, vilket betyder att det finns 16 tal istället för 10. Talen 10, 11, 12, 13, 14 och 15 motsvaras av A, B, C, D, E och F. För varje skift åt vänster av ett av dessa tal motsvarar en multiplikation med 16 i det decimala talsystemet. Så här konverterar man värdet av "FF" till ett decimalt tal:

Observera att "F" betyder 15
FF = (F*16)+F = (15*16)+15 = 255

Ett annat exempel:

Observera att "A" betyder 10 och "E" betyder 14)
E28A = (E*16*16*16)+(2*16*16)+(8*16)+A = 57994

Så varför bör man använda hexadecimala tal när man håller på med pixelbehandling? Det är faktiskt mycket lättare att arbeta med dem, eftersom pixelvärdets tal delas upp i fyra grupper som då exakt representerar de fyra komponenterna. Du kan t.ex. ändra på blåkomponenten i färgvärdet genom att manipulera de två första talen. Du får mindre kod och det är lättare att se vad färgen är. Ett exempel:

I  pixelvärdet FF030303 kan du genast se att det 
motsvarar ett alfa-värde på 255 samt ett värde på 3 
för både rött, grönt och blått. Decimalt så är 
värdet 4278387459, där det är BETYDLIGT svårare att läsa
av färgvärderna.

Jag kommer inte att gå igenom mer om hexadecimala tal i den här kursen. Om du inte är så hemma på det kan du använda Windows räknaren i avancerad läge (scientific mode) för att kunna konvertera mellan decimala- och hexadecimala tal. Jag brukar själv använda det. I Java skriver man hexadecimala färgvärden på följande sätt:

int redvalue = 0xff0000;
int greenvalue = 0xff00;
int bluevalue = 0xff;

Observera att alfa-kanalen i värdena ovan är 0. Om man skall använda dessa som färgpixelvärden som man vill skall SYNAS så bör man lägga till ett fullt värde på alfa kanalen (FF):

int redvalue = 0xffff0000;
int greenvalue = 0xff00ff00;
int bluevalue = 0xff0000ff;

Anta nu att vi har fyra int-variabler: "a", "r", "g" och "b". Dessa variabler representerar alfa-kanalen och färgkomponenterna samt har värden mellan 0 och 255. Hur bygger man upp ett färgvärde med dessa variabler? Jo, så här:

int colorvalue = a*256*256*256 + r*256*256 + g*256 + b;

Som du ser multiplicerar vi varje komponent ett antal gånger med 256 så att värdet hamnar på rätt "plats" i färgvärdet. Hur många färgvärden innehåller appletskärmen, egentligen? Ja, hur stor skärm har DU specifierat i resize() metoden? Om du har specifierat en skärm med bredden 200 och höjden 300 så har du 200x300 = 60000 färgvärden att hålla reda på (dvs 60000 int-värden). Att behandla alla dessa pixlar kan ta tid. Nu vet du en av orsakerna till varför bildbehandling kan vara processorkrävande.


Nästa sida >>