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[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

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!! :(