Programowanie w języku C/C++ » Artykuły

ScanLine w C

  • 2007-10-26 14:14
  • 6 komentarzy
  • 959 odsłon
  • Oceń ten tekst jako pierwszy
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

JaskMar 2007-10-26 14:12

Format jest BGR, tylko w kodzie była pomyłka

brightshadow 2007-10-23 20:59

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 :)

Piotrekdp 2007-03-27 11:40

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 :)

gawron86 2006-12-03 19:24

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.

Coldpeer 2006-05-27 18:40

Przydałoby się trochę formatowanie polepszyć, literówki - ja niestety teraz nie mam na to czasu :P

Piotrekdp 2006-05-27 12:14

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