Delphi - MaskBlt nem csak NT-re

forráskód letöltése
Amikor egy olyan képet szeretnénk másolni egy másik képre, aminek alakja nem szabályos téglalap, hanem például egy betű, akkor erre több lehetőségünk is van. Az átlátszó részeket például kifestjük egy olyan színnel, ami egyébként nem szerepel a képen, majd a megfelelő függvénnyel másoljuk a képet úgy, hogy megadjuk az átlátszó színt. A másik megoldás, hogy egy ún. maszkot használunk, ami egy fekete-fehér bitkép. Ahol a maszk pixeleinek színe fekete, ott az eredeti kép látható, míg ahol a pixelek színe fehér, ott a másolt kép pixelei jelennek meg. A mellékelt példában egy olyan eljárást készítünk, ami ezt a feladatot oldja meg. Van ugyan egy ilyen Windows függvény, ami hasonló feladatot lát el, ez a MaskBlt. Ez viszont csak Windows NT esetén használható. A most készítendő eljárás paraméterezésében egyszerűbb, így a lehetőségei is korlátozottabbak, viszont a bevezetőben említett feladatot tökéletesen ellátja.
procedure MaskCopy(hdcDest: HDC; nXDest, nYDest, nWidth, nHeight: integer;
                  hdcSrc: HDC; nXSrc, nYSrc: integer; hdcMask: HDC);
A paraméterek jelentése a következő:
hdcDest: annak a Canvas-nak az azonosítója, amire a képet másolni szeretnénk (Handle).
nXDest, nYDest: a célterület X és Y koordinátája.
nWidth, nHeight: a célterület szélessége és magassága.
hdcSrc: annak a Canvas-nak az azonosítója, amiről a képet másolni szeretnénk.
nXSrc, nYSrc: a forrásterület X és Y koordinátája.
hdcMask: a maszk Canvas-ának azonosítója. Ez egy fekete-fehér kép kell, hogy legyen.

Az eljárásban létrehozunk két átmeneti bitképet, amin a szükséges műveleteket végrehajtjuk.
A TempSrc bitképre átmásoljuk a forrásképet, majd a maszk-ot is a következőképpen:
    BitBlt(Canvas.Handle, 0, 0, Width, Height, hdcSrc, nXSrc, nYSrc, SRCCOPY);
    BitBlt(Canvas.Handle, 0, 0, Width, Height, hdcMask, 0, 0, MERGEPAINT);
Az első másolás egy az egyben átmásolja a forrásképet az átmeneti képre. A második másolásnál a maszkot másoljuk a MERGEPAINT logikai művelettel. Ez azt jelenti, hogy ami a maszk képen fekete volt, az átmeneti képen fehér lesz, ami pedig fehér volt, ott az eredeti kép fog látszani, vagyis a forráskép.

A TempDest átmeneti képet hasonlóképpen hozzuk létre, de itt már a célképet használjuk fel, és a második másolásnál az SRCPAINT logikai műveletet használjuk fel:
    BitBlt(Canvas.Handle, 0, 0, Width, Height, hdcDest, nXDest, nYDest, SRCCOPY);
    BitBlt(Canvas.Handle, 0, 0, Width, Height, hdcMask, 0, 0, SRCPAINT);
Az SRCPAINT logikai művelet eredménye pont fordítottja lesz a MERGEPAINT-nak, vagyis ahol a maszk pixeleinek színe fekete volt, ott az eredeti kép pixelei fognak látszani, ahol pedig fehér volt, ott a pixelek színe fehér lesz.

Ha megvan a két átmeneti kép, akkor ezeket szintén összemásoljuk:
  BitBlt(TempDest.Canvas.Handle, 0, 0, nWidth, nHeight,
         TempSrc.Canvas.Handle, 0, 0, SRCAND);
Itt már az SRCAND logikai műveletet használjuk, aminek eredménye a kívánt kép lesz, tehát ezt még egy másolással átmásoljuk a célképre, és készen is vagyunk:
  BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, TempDest.Canvas.Handle, 0, 0, SRCCOPY);