Witam. Początkowo pytałem się jak zrobić filtr na pixelizacje obrazu (mosaic/pixelate)... ale juz sam do tego doszedłem i wydaje mi się, że warto byłoby utworzyć w tym dziale temat z różnymi algorytmami itp. Dlatego też zamieszczam filtr na pixelizacje:
Tak to wygląda w praktyce: SetMosaic (5) ;
Małe objaśnienie do kodu:
-
Funkcja jest składową klasy image, pisanej przeze mnie... Klasa ta przechowuje szerokość, wysokość obrazka (iWidth, iHeight) oraz wskaznik do bitów obrazka (pImage). Każdy pixel obrazka jest zapisywany na 32 bitach (RGBA = 8 bitów - czerwony, 8 bitów - zielony, 8 bitów - niebieski, 8 bitów - kanał przezroczystości)
-
W zmiennych iR, iG, iB, iA są przechowywane sumy odpowiednio czerwonej, zielonej, niebieskiej, "alpha" barwy z jednej komórki. Wielkość komórki określa parametr funkcji iCell, i tak jeśli będzie równy 4. To zmienne iR, iG... będą przechowywały sumę barw z czterech kolejnych pixeli. Następnie obliczana jest średnia tych pixeli i taka średnia jest zapisywana do całej komórki czyli do obrazka o wielkości 4 x 4 px. Filt uwzględnia też tzw. komórki ucięte. Czyli jeśli obraz miał 300 x 300 px, a iCell zostało ustawione na 7 to 300 / 7 daje nam 42 i jeszcze 6 pixeli. Tak więc dla krańcowych komórek jest wykonywana oddzielna operacja na obliczanie średniej barwy pixela. Suma barw 6 pixeli nie jest dzielona na 7 a na 6 (średnia arytmetyczna)...
Tyle wyjaśnienia chyba wystarczy... pozdrawiam :)
/*______________
Filtr mosaic
______________*/
BOOL image::SetMosaic (int iCell)
{
// Wartość bezwzględna z wielkości komórki
if (iCell < 0)
{
iCell *= -1 ;
}
// Ustawienie wskaźnika i zmiennych przechowujacych sumę barw
RGBA * rgba = (RGBA *) pImage ;
int iR = 0 ;
int iG = 0 ;
int iB = 0 ;
int iA = 0 ;
// Poziomy przebieg pętli
for (int y = 1; y <= iHeight; y++)
{
for (int x = 1; x <= iWidth; x++, rgba++)
{
iR += rgba->rgbaR ;
iG += rgba->rgbaG ;
iB += rgba->rgbaB ;
iA += rgba->rgbaA ;
if (x % iCell == 0)
{
iR = iR / iCell ;
iG = iG / iCell ;
iB = iB / iCell ;
iA = iA / iCell ;
for (int i = 0; i < iCell; i++)
{
rgba->rgbaR = iR ;
rgba->rgbaG = iG ;
rgba->rgbaB = iB ;
rgba->rgbaA = iA ;
rgba-- ;
}
rgba += iCell ;
iR = 0 ;
iG = 0 ;
iB = 0 ;
iA = 0 ;
}
else if (x == iWidth)
{
iR = iR / (iWidth % iCell) ;
iG = iG / (iWidth % iCell) ;
iB = iB / (iWidth % iCell) ;
iA = iA / (iWidth % iCell) ;
for (int i = 0; i < iWidth % iCell; i++)
{
rgba->rgbaR = iR ;
rgba->rgbaG = iG ;
rgba->rgbaB = iB ;
rgba->rgbaA = iA ;
rgba-- ;
}
rgba += iWidth % iCell ;
iR = 0 ;
iG = 0 ;
iB = 0 ;
iA = 0 ;
}
}
iR = 0 ;
iG = 0 ;
iB = 0 ;
iA = 0 ;
}
// Pionowy przebieg pętli
for (int x = 1; x <= iWidth; x++)
{
rgba = (RGBA *) pImage ;
iR = 0 ;
iG = 0 ;
iB = 0 ;
iA = 0 ;
rgba += x - 1 ;
for (int y = 1; y <= iHeight; y++, rgba += iWidth)
{
iR += rgba->rgbaR ;
iG += rgba->rgbaG ;
iB += rgba->rgbaB ;
iA += rgba->rgbaA ;
if (y % iCell == 0)
{
iR = iR / iCell ;
iG = iG / iCell ;
iB = iB / iCell ;
iA = iA / iCell ;
for (int i = 0; i < iCell; i++)
{
rgba->rgbaR = iR ;
rgba->rgbaG = iG ;
rgba->rgbaB = iB ;
rgba->rgbaA = iA ;
rgba -= iWidth ;
}
rgba += iWidth * iCell ;
iR = 0 ;
iG = 0 ;
iB = 0 ;
iA = 0 ;
}
else if (y == iHeight)
{
iR = iR / (iHeight % iCell) ;
iG = iG / (iHeight % iCell) ;
iB = iB / (iHeight % iCell) ;
iA = iA / (iHeight % iCell) ;
for (int i = 0; i < iHeight % iCell; i++)
{
rgba->rgbaR = iR ;
rgba->rgbaG = iG ;
rgba->rgbaB = iB ;
rgba->rgbaA = iA ;
rgba -= iWidth ;
}
rgba += iWidth * (iHeight % iCell) ;
iR = 0 ;
iG = 0 ;
iB = 0 ;
iA = 0 ;
}
}
}
return TRUE ;
}
dorzycam jeszcze deklaracje funkcji i struktury RGBA
#include <windows.h>
#define COLOR 0
#define COLORALPHA 1
typedef struct tagRGBA
{
BYTE rgbaB ;
BYTE rgbaG ;
BYTE rgbaR ;
BYTE rgbaA ;
} RGBA ;
class image
{
public:
BYTE * pImage ;
int iWidth ;
int iHeight ;
BYTE * LoadImageFromFile (PTSTR pstrFileName) ;
BYTE * GetScreen (HWND hwnd, int xPos, int yPos) ;
BOOL SetImageFromFile (TCHAR * szFileName, TCHAR * szExtension) ;
BOOL SetImageFromBitmap (HBITMAP hBitmap) ;
BOOL SetAlpha (image * pImage) ;
BOOL SetGreyscale (void) ;
BOOL SetInvert (void) ;
BOOL SetBrightness (int iBrightness) ;
BOOL SetColorBalance (int iRed, int iGreen, int iBlue) ;
BOOL SetSepia (void) ;
BOOL SetSolarize (void) ;
BOOL SetMosaic (int iCell) ;
BOOL SetPixelRGBA (int xPos, int yPos, BYTE bRed, BYTE bGreen, BYTE bBlue, BYTE bAlpha) ;
RGBA GetPixelRGBA (int xPos, int yPos) ;
BOOL Display (HWND hwnd, int xPos, int yPos, int iFlag) ;
~image()
{
delete pImage ;
}
} ;
</image>