ScanLine w C
Piotrekdp
ScanLine w C++
W Bitmapie kolory zapisane są w kolejności Blue Green Red czyli <font color="blue">B</span> <font color="green">G </span><font color="red">R</span>
zapis wygląda tak :
<font color="blue">B</span><font color="green">G</span><font color="red">R</span> <font color="blue"> B</span><font color="green">G</span><font color="red">R</span><font color="blue"> B</span><font color="green">G</span><font color="red">R</span>....
W zależności od formatu pixeli bitmapy kolory są reprezentowane przez różną liczbe bajtów :
pf32bit - 4 bajty
pf24bit - 3 bajty
pf16bit - 2 bajty
pf8bit - bajt
Scan Line w zależności od użytych zmiennych i formatu pixela czyta odpowiednią ilosć bajtów
jednak najlepiej pracować na bitmapie o parametrach pf24 bit czyli 1 pixel - 3 bajty.
do objaśnienia dalszej części
posłuże się przykładem(kod na skale szarości):
*ScanLine Przy użyciu *byte (format pixela dowolny czytamy bajt po bajcie)
const char RConst = 77;
const char GConst = 150;
const char BConst = 29;
int Index ;
int H ;
int V ;
Graphics::TBitmap* Bitmapa = new Graphics::TBitmap; // Bitmapka której scan przeprowadzam
///Tutaj sobie ją wczytujemy bądz rysujemy a potem...
Bitmapa->PixelFormat =pf24bit; //Ustawiam format pixeli na 24 bitowy
for ( V = 0; V<Bitmapa->Height; V++)
{
char* p = (char*)Bitmapa->ScanLine[V]; // ustawiam wskaźnik do char na Linii bitmapy (używam char, bo zajmuje tylko jeden bajt, a nam więcej nie potrzeba)
for ( H = 0; H<Bitmapa->Width; H++) //w pentelce przez cała szerokość bitmapki robimy....
{
Index = (p[H*3+2] * RConst + // mnożymy kanały BGR przez stałe
p[H*3+1]* GConst +
p[H*3]* BConst )>>8; // przesuwamy bity o 8 w prawo
p[H*3]=Index;
p[H*3+1]=Index;
p[H*3+2]=Index;
}
}
I teraz wyjaśnienie :
Zmienna H przedstawia nam numer pixela w linii w bitmapce (liczony od 0)
p[H3] -kolor niebieski w pixelu
p[H3+1] -kolor zielony w pixelu
p[H*3+2] -kolor czerwony w pixelu
Te mnożenia występują tutaj dlatego , że czytamy "bajt po bajcie" a ponieważ bitmapa jest 24 bitowa wiec pojedyńczy pixel ma 3 bajty
*ScanLine Przy użyciu *TRGBTriple(format pixela pf24bit)
W tym typie wystąpują trzy składowe
rgbtBlue; (bajt "niebieski")
rgbtGreen; (bajt "zielony")
rgbtRed; (bajt "czewony")
( to samo dla porównania)-tutaj ScanLine pakuje nam składowe pixela do rekordów więc "mnożeń" niema
const char RConst = 77;
const char GConst = 150;
const char BConst = 29;
int Index ;
int H ;
int V ;
Graphics::TBitmap* Bitmapa = new Graphics::TBitmap; // Bitmapka której scan przeprowadzam
for ( V = 0; V<Bitmapa->Height; V++)
{
TRGBTriple * row = (TRGBTriple *)Bitmapa->ScanLine[V]; // ustawiam wskaźnik na Linii bitmapy typu TRGBTriple (o nazwie row)
for ( H = 0; H<Bitmapa->Width; H++) //w pentelce przez cała szerokość bitmapki robimy....
{
Index = (row[H].rgbtRed * RConst +
row[H].rgbtGreen * GConst +
row[H].rgbtBlue * BConst )>>8;
row[H].rgbtRed=Index;
row[H].rgbtGreen=Index;
row[H].rgbtBlue=Index;
}
}
*ScanLine Przy użyciu *RGBQUAD (analogicznie jak powyżej tylko że pf32bit)
W tym typie wystąpują cztery składowe:
rgbBlue; (bajt "niebieski")
rgbGreen; (bajt "zielony")
rgbRed; (bajt "czewony")
rgbReserved (bajt "rezerwowy")
UWAGA!!!
Aby wszystko działało poprwnie trzeba zwrócić uwagę na szerokość bitmapki
format pixela i rodzaj użytej zmiennej !!
inaczej wyjdziemy poza zakres bitmapki i pojawi się błąd.
Format jest BGR, tylko w kodzie była pomyłka
Z tym zapisem bitmapy w formacie BGR bym się zastanawiał....
Przyjrzyj się jak odczytujesz dane...
najpierw R = p[3x], później G = p[3x + 1] itd.
Więc chyba jednak w formacie RGB co?? :p
Ogólnie kod przydatny :)
Zarzut 1 : int czy integer obydwa typy są przyjmowane (choć być może kompilatory nie przyjmują)
Zarzut 2 : TRGBTriple * row takie coś to już deklaracja zmiennej , można w"biegu pisać"
ten kod pisałem W Borland C++ Enterprise , Jest to kompilator z wbudowanym Typem
TBitmap więc tam gdzie tego nie ma np
w Dev C++ to już ci niezadzała
B.T.W Kod był Sprawdzony i działa :)
jesli to ma byc w c++ to chyba żle sa zadeklarowane zmienne.. pisze sie int a nie Integer. Po drugie zapomniano tu zadeklarowac kilku zmiennych ktore wystepuja w kodzie, np. p lub row.
PS. jak w ogole korzystac z tej grafiki, jak ją zadeklarowac. .bo te wszystkie funkcje od grafiki mi wyskakują jako błędy? przepraszam, ale slabo sie znam, prosze o wyrozumialosc.
Przydałoby się trochę formatowanie polepszyć, literówki - ja niestety teraz nie mam na to czasu :P
INFO DLA MODERATORÓW
niestety w trakcie pisania troche bezmyślnie stworzyłem 6 wersji tego artykułu
jakby ktoś mógł skasować historie to by dobrze było bo toszke zaśmieciłem serwis
przepraszam za kłopot!! :(