ScanLine w C
W Bitmapie kolory zapisane są w kolejności Blue Green Red czyli B G R
zapis wygląda tak :
BGR BGR BGR....
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[H*3] -kolor niebieski w pixelu
p[H*3+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.
6 komentarzy
Z tym zapisem bitmapy w formacie BGR bym się zastanawiał....
Przyjrzyj się jak odczytujesz dane...
najpierw R = p[3*x], później G = p[3*x + 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!! :(
Format jest BGR, tylko w kodzie była pomyłka