Delphi - TPixelateEffect komponens

Bitmap effektek 14. rész

forráskód letöltése
Ennél az effektnél az éppen látható képet „elpixelesítjük” egyre nagyobb mértékben, majd egy adott lépésszám után ugyanezt tesszük a megjelenítendő képpel, de fordított irányba. Ez a képváltási effektus viszonylag bonyolult, de nagyon látványos.
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;

Bitmap effektek cikksorozat