
A mellékelt példaprogram megnyitása előtt a PixelateEffect.pas-ban lévő komponenst telepítenie kell a Delphi alá. A komponens telepítéséhez szükség van továbbá a cikksorozat első részéhez mellékelt BaseEffect unit-ra.
A Pixelate effekt a következőképpen néz ki: a kép pixeleit minden lépésben a kétszeresére növeljük úgy, hogy közben a kép mérete nem változik. Ezt úgy érjük el, hogy létrehozunk egy pontosan fele akkora képet, mint az eredeti kép. Ez azt jelenti, hogy egy 2x2 pixel méretű képrészletből egyetlen pixel lesz. Ennek a pixelnek a színe a négy pixel színének átlagából adódik. Amikor elkészült a kis kép, akkor az eredeti kép méretére nagyítjuk. Ha ezt több lépésben elvégezzük, akkor egy olyan animációt kapunk, amiben a kép egyre nagyobb pixelekből fog felépülni, míg végül teljesen felismerhetetlen lesz.
Az animáció két lépésben történik. Az első lépésben az éppen látható képet pixelesítjük el olyan mértékben, ahogy azt a ZoomStep property értéke meghatározza. A második lépésben megjelenítjük a második képet, ugyanolyan mértékben pixelesítve, mint az első kép volt, majd ennek mértékét folyamatosan csökkentjük. Az animáció utolsó lépésében már az eredeti képet fogjuk látni.
A komponensben a pixelesítést a Pixelate eljárás végzi. Ennek paramétereként meg kell adni egy TBitmap objektumot. Az eljárás tartalmaz egy belső függvényt, ami négy szín összetevőiből előállítja a színek átlagát, és ezzel tér vissza.
function AvgColor(r1, g1, b1, r2, g2, b2, r3, g3, b3, r4, g4, b4: word):TColor;
begin
result:=RGB(
Round((r1+r2+r3+r4)/4),
Round((g1+g2+g3+g4)/4),
Round((b1+b2+b3+b4)/4));
end;
Az eljárásban létrehozunk egy TBitmap objektumot, amit az új kép átmeneti tárolására használunk. Ez pontosan fele akkora lesz, mint az a kép, amit pixelesítünk.
begin
dest:=TBitmap.Create;
dest.Width:=img.Width div 2;
dest.Height:=img.Height div 2;
dest.Dormant;
Egy ciklussal végigmegyünk az eredeti képen, és lekérdezzük annak pixeleit négyesével, vagyis 2x2 pixelenként. A függvény meghívásával megkapjuk a négy pixel színének átlagát, ami az új kép megfelelő pixelének színe lesz.
for y:=0 to dest.Height-1 do begin
y1:=img.ScanLine[y*2];
y2:=img.ScanLine[y*2+1];
y3:=dest.ScanLine[y];
for x:=0 to dest.Width-1 do begin
c1:=x*2;
c2:=x*2+1;
pix:=AvgColor(
y1[c1].rgbtRed, y1[c1].rgbtGreen, y1[c1].rgbtBlue,
y1[c2].rgbtRed, y1[c2].rgbtGreen, y1[c2].rgbtBlue,
y2[c1].rgbtRed, y2[c1].rgbtGreen, y2[c1].rgbtBlue,
y2[c2].rgbtRed, y2[c2].rgbtGreen, y2[c2].rgbtBlue);
y3[x].rgbtRed:=GetRValue(pix);
y3[x].rgbtGreen:=GetGValue(pix);
y3[x].rgbtBlue:=GetBValue(pix);
end;
end;
Amikor elkészült a kis kép, akkor a paraméterként megkapott TBitmap típusú objektumba másoljuk.
img.Assign(dest);
dest.Free;
end;