Transparența este ușoară

Windows 98 și biblioteca msimg32.dll

Înainte de a începe, vom vedea că ne înțelegem:
  • Bitmap, bitmap - o imagine dreptunghiulară formată din pixeli.
  • Pixel - elementul minim al imaginii, punctul de pe ecran sau în memoria rasterului.
  • Transparența - proprietatea unor pixeli nu este afișată pe dispozitivul de ieșire, lăsând imaginea originală neschimbată.
  • Translucența este o interacțiune a pixelilor în care atât pixelii rasterului de ieșire, cât și imaginea de fundal sunt vizibili.
  • Sprite este o imagine bitmap cu zone transparente și semi-transparente.

De ce avem nevoie de imagini raster cu transparență sau semi-transparență a zonelor individuale? Acestea sunt elemente importante ale interfeței grafice Windows pe care o puteți viziona de fiecare dată când porniți computerul. Icoanele de pe desktop au zone transparente, ceea ce vă permite să vedeți "prin" ele. Când trageți un obiect, lucrați în folderul Windows 98, pictograma sa devine semi-transparentă, permițându-vă să vedeți ce se află în acest moment. Și, în sfârșit, nu ar trebui să uităm de astfel de programe "grafice-intensive" ca și jocuri. Este greu de imaginat că, într-un spațiu planificat cu atenție spațiu "shooter" toate navele au avut o formă dreptunghiulară. Iar atunci când facem explozii, este de dorit să le facem translucide, aducând imaginea mai aproape de realitate.







De fapt, pe acest subiect au scris destul de mult. Pentru a înțelege mecanismele de bază pentru obținerea efectelor de transparență, vă recomand să citiți articolul lui Ron Jerry "Bitmapuri cu transparență" (puteți găsi în MSDN în secțiunea Technical Articles-> Multimedia-> GDI). De asemenea, recomand să studiez articolele lui Dale Rogerson ("Sprites Make the World Go Round") și Herman Rodent ("Animație în Win32").

Windows 95 și liste de imagini

Odată cu lansarea Windows 95 la dispoziția programatorilor a fost o bibliotecă comodă de Common Controls. În compoziția sa nu au fost doar noi (acum cunoscute de toate) de control, dar, de asemenea, o componentă non-vizual - Lista de control de imagine. Scopul său principal este de a păstra un set de imagini de aceeași dimensiune. Acest lucru este convenabil pentru utilizarea într-o varietate de elemente - de exemplu, în barele de instrumente:

Suntem mai interesați de o altă posibilitate interesantă - de a stoca informații despre transparența listelor de imagini. Acest lucru se realizează în două moduri:

  • Prin descărcarea unei imagini bitmap care indică ce pixeli ai culorii sunt considerați transparenți;
  • Pregătiți o mască de transparență specială - un raster alb-negru, în care pixelii de culoare neagră înseamnă transparență pentru punctele corespunzătoare ale rasterului principal. În acest caz, masca de transparență trebuie să aibă aceleași dimensiuni ca și raster-ul principal.

Trebuie să înțelegeți că în ambele cazuri, lista de imagini va conține o mască de transparență, doar primul mod în care va fi creat pentru dvs. Ce modalitate de a alege este o chestiune de gust pentru fiecare programator. De obicei, găsesc în paletă o culoare inutilă și o atribuie transparenței. În majoritatea cazurilor, nici un noroc cu culoarea violet luminos (RGB = (255,0255)), dar de data aceasta pentru a demonstra efectul de transparență, am ales alb:


Creați liste de imagini transparente

Pentru a crea o listă de imagini și a încărca un bitmap cu transparență în ea, puteți face acest lucru:

În exemplele se va presupune că sunt programe de resurse bitmap-uri și au o adâncime de culoare de 24 de biți (16 milioane. Culori). Când creați o listă, trebuie să specificați dimensiunea raster încărcate (cx, cy), formatul de culoare (ILC_COLOR24, 16 milioane de culori) și un semn al prezenței măștii (ILC_MASK). Ultimii doi parametri Creare () determină numărul de imagini stocate în listă și valoarea incrementului listei în absența spațiului. Macro-ul RGB este convenabil pentru specificarea culorii în gama de 24 de biți, în acest caz - culoarea transparenței.

În principiu, puteți încărca o imagine cu un singur apel, dar această metodă nu acceptă imagini pline color (ca în exemplul nostru):

Implicit, un astfel de raster este limitat la 16 culori.

Desenare cu lista de imagini

De ce listele de imagini sunt într-adevăr utile, astfel încât aceasta să faciliteze lucrarea de desen. Vă amintiți numărul și ordinea parametrilor pentru BitBlt ()? Și inconvenientele sale din cauza necesității de a pregăti un context de dispozitiv suplimentar în memorie? Toate acestea pot confunda nu numai începătorul, ci și cel mai experimentat programator.

Situația este și mai complicată atunci când avem de-a face cu transparența. Este necesar să se afișeze imaginea de mai multe ori cu diferiți parametri ai operațiilor raster (Raster Operation, ROP). De fiecare dată când vom afișa o mică imagine a unei nave spațiale, este necesar să facem o mulțime de lucruri.

Din fericire, programatorii Microsoft l-au făcut deja pentru noi. Puteți desena un bitmap din lista de imagini prin simpla apelarea funcției ImageList_Draw (). Cu MFC, acest apel arată astfel:







Aici pDC este un pointer la contextul dispozitivului (CDC), 0 este numărul de ordine al imaginii de ieșire din listă, m_drawPoint este coordonatele începutului zonei de ieșire. Steagul ILD_TRANSPARENT indică faptul că ieșirea trebuie făcută cu masca de transparență.

Pentru cele mai curioase, vă spun că realizarea efectului de transparență este realizată prin metoda pe care Ron Jerry o numește Metoda sursei negre, adică "metoda sursă neagră". Acesta vă permite să afișați o imagine cu zone transparente în două apeluri către BitBlt () în loc de trei, dar vă cere să înlocuiți mai întâi pixelii care sunt transparenți, negri. Prin urmare, când încărcați o imagine bitmap în lista de imagini, o schimbați.

Rezultatul apelului va fi ceva de genul:

Windows 98 și biblioteca msimg32.dll

Windows 98 a adus o nouă modalitate ușoară de a afișa imagini transparente. Biblioteca msimg32.dll pe care o conține conține funcții noi pentru a obține efecte grafice grabnice. Pentru ao folosi, trebuie să conectați fișierul msimg32.lib la proiect în timpul construcției.

Acum puteți afișa un bitmap cu transparență într-un singur pas folosind funcția TransparentBlt, specificând culoarea transparentă din ultimul parametru al funcției:

"Wow - la un moment dat!" vei spune. vei avea dreptate. Din nou, este nevoie de un context compatibil al dispozitivului în care să se selecteze rasterul de ieșire. Din nou - o lungă (și nu intuitivă) listă de parametri. Dar au existat oportunități de a controla producția. În acest exemplu, x, y, x1, y1 sunt coordonatele punctului de pornire al raster-ului în receptor, respectiv sursa. Parametrii dstX și dstY sunt dimensiunile zonei de ieșire, iar srcX și srcY sunt lățimea și înălțimea dreptunghiului afișate din raster. Ce se întâmplă dacă le-am stabilit diferite valori? Rezultatul este dat aici:

După cum puteți vedea, această funcție conține opțiuni pentru comprimarea / întinderea imaginilor raster. Nu exagerați și nu treceți valori negative ca dimensiuni - nu puteți crea o imagine oglindă a TransparentBlt ().

Să adăugăm că funcția TransparentBlt () la ieșire se bazează pe capabilitățile DirectX ale acestui dispozitiv, ceea ce poate da un câștig de performanță în comparație cu metodele tradiționale.

consiliu
Nu uitați să utilizați din nou contextul dispozitivului pentru a selecta rasterul inițial (temp în exemplul nostru). În caz contrar, resursele grafice ale sistemului se vor scurge.

AlphaBlend (): "Semi" - nu neapărat 1/2

Toate metodele de mai sus lucrează cu un singur model de transparență, numit grafica grafică a computerului Chroma. Aceasta înseamnă că o anumită culoare este atribuită unei culori transparente. Un alt model mai dezvoltat se numește Alpha Blending. Atunci când este utilizat, transparența (Alpha) este utilizată pentru a descrie caracteristicile pixelilor, cu excepția componentelor de culoare (R, G, B). Gradul de transparență este determinat de reciprocitatea acestui parametru.

Scopul parametrilor, în general, este clar din prototip. De interes deosebit este ultimul parametru - BLENDFUNCTION. Este o structură (dintre toate cele patru octeți) care definește modul de ieșire.

Ce este? Faptul este că AlphaBlend () poate funcționa în două moduri diferite.

Mod simplu (transparență generală)

Primul (și cel mai ușor de utilizat) mod AlphaBlend () presupune că valoarea Alpha este setată pentru întreaga imagine. În acest caz, se aplică tuturor pixelilor fără excepție:

Acest rezultat a fost obținut cu acest format BLENDFUNCTION:

Pentru câmpul BlendOp, în prezent este definită o singură valoare valabilă - AC_SRC_OVER.
Câmpul BlendFlags trebuie să conțină 0.
Un parametru AlphaFormat slab documentat determină interacțiunea pixelilor sursă și a receptorului, despre care vom vorbi mai departe.
Parametrul SourceConstantAlpha determină gradul de opacitate. Setând 0 pentru acest câmp, nu veți vedea raster-ul deloc. Valoarea maximă care se potrivește tipului BYTE este 255. Rasterul de ieșire înlocuiește complet zona de destinație. Dar de ce ar trebui, deci, AlphaBlend ()? Această valoare este utilizată, în principal pentru al doilea mod.

Mod cu canal alfa

Aceasta necesită o pregătire suplimentară. În acest mod, rasterul pregătit pentru ieșire trebuie să conțină informații despre gradul de transparență al fiecărui pixel. Acest lucru este realizat, de exemplu, prin aplicarea unui format de 32 de biți pe pixel (un octet pentru fiecare componentă de culoare și unul cu un canal alfa).

Dificultăți vor apărea cu acest lucru. Nu știu niciun pachet grafic care vă permite să salvați rasteri cu un canal alfa într-un format potrivit pentru AlphaBlend (). Atunci când creați un astfel de raster în mod programatic, îl putem salva pe disc (în format Windows Bitmap pe 32 de biți). Este citit de programe populare precum ACDSee, dar funcțiile LoadBitmap () și LoadImage () refuză să o încarce. Când am încercat să o pun în resursa rc.exe, am căzut cu mesajul Eroare internă.

Dar nu fi descurajat. Putem pregăti un raster în memorie, combinând, de exemplu, două rastere - cu imaginea obiectului și a umbrei acestuia. Din fericire, funcția AlphaBlend () poate funcționa cu rasterele create cu CreateDIBSection ():

Aici hdc este contextul compatibil cu dispozitivul de ieșire, pbmi este un pointer la structura BITMAPINFO cu informații despre dimensiunile și adâncimea de culoare a raster-ului creat. Parametrul iUsage specifică faptul că indicii din paleta de culori (DIB_PAL_COLORS) sau valorile lor directe (DIB_RGB_COLORS) vor fi conținute în tamponul raster. Evident, al doilea - pentru modul TrueColor, paleta nu este necesară.
Un pointer la tamponul creat într-un apel de succes va fi returnat în parametrul ppvBits.
În parametrii hSection și dwOffset, atunci când se lucrează cu raster în memorie, trebuie specificat 0.

remarcă
Toate cele de mai sus nu înseamnă că sprite cu un canal alfa nu pot fi stocate în resursele programului. Puteți să le includeți ca o resursă particularizată, să încărcați utilizând LoadResource () și să completați datele cu buffer-ul creat cu CreateDIBSection (). Dar nu uitați că acest lucru va crește semnificativ dimensiunea executabilului. În plus, puteți lua în considerare opțiunea de încărcare pre-calculată într-un raster de programe similar din fișiere externe - instrumentele de bibliotecă de execuție sau folosind parametrii hSection și dwOffset la apelarea CreateDIBSection ().

Utilizarea lui CreateDIBSection () ușurează accesarea biților imaginii: în caz contrar, puteți afișa astfel de imagini numai în modul True Color pe 32 biți. Pentru a gestiona acest format de date, structura RGBQUAD este ideală:

Canalul alfa poate fi stocat în câmpul rgbReserved, deși nu a fost destinat pentru asta :) În plus, există încă o posibilitate (fără documente) de a utiliza funcția AlphaDIBBlend (), pe care nu o vom lua în considerare.

Rezultatul este dat aici:

Vom omite detaliile de lucru cu biți de rasteri (toate acestea pot fi găsite în proiectul atașat). Am notat doar că ieșirea a folosit acest format BLENDFUNCTION:

consiliu
Când utilizați un canal alfa, aveți în continuare opțiunea de a modifica transparența întregii imagini fără a recalcula biții imaginii - SourceConstantAlpha funcționează și în acest caz.

În sfârșit, vă reamintesc că AlphaBlend () necesită, de asemenea, includerea în proiect a msimg32.lib, care lipsește din Windows 95, atunci când se construiește biblioteca de import.







Articole similare

Trimiteți-le prietenilor: