Bitmap 의 구조

Delphi 2009. 4. 18. 20:38










위의 이미지는 2x2 크기의 비트맵을 Hex Editor 로 열었을 때의 구조에 대한 분석이다.

이미지는 회색 2픽셀과 그 아래 흰색 2픽셀이라고 가정했을 때의 예이다.

Offset 00 ~ Offset 35 까지는 Header 에 해당하고,

Offset 36 부터 끝까지 픽셀에 대한 정보가 담겨 있다.

 

header 의 각 정보가 궁금하면 아래의 URL 로 방문해보면 다 있다.

http://en.wikipedia.org/wiki/Windows_bitmap

 

픽셀에 대한 정보가 들어있는 부분 사이사이에 의미없는 00 00 같은 것이 보이는 데, (Offset = 3C, 3D, 44, 45)

설명에 달아놨듯이 null byte padding 이라는 것이다.

한 라인이 4 byte 로 떨어지지 않으면 임의로 4 byte 씩 맞추기 위해 추가한 의미없는 null 값이다.

 

 

 

 

아래와 같은 코드를 통해 포인터 위치를 출력해 보았다.

 

procedure TForm1.Button1Click(Sender: TObject);
var
  btm: TBitmap;
  PLine: PByteArray;
  X, Y: Integer;

begin
  btm:=TBitmap.Create;
  try
    btm.LoadFromFile('C:\Documents and Settings\백충덕\바탕 화면\2.bmp');

    for Y:=0 to btm.Height-1 do begin
      PLine:=btm.ScanLine[Y];
      for X:=0 to btm.Width-1 do begin
        Memo1.Lines.Add(Format('(%d:%d) R:%p, G:%p, B:%p', [X,Y,@PLine[2+(X*3)],@PLine[1+(X*3)],@PLine[X*3]]));
      end;
    end;

  finally
    FreeAndNil(btm);
  end;
end;

 

 

결과값은 아래와 같다.

 

(0:0) R:0116000A, G:01160009, B:01160008
(1:0) R:0116000D, G:0116000C, B:0116000B
(0:1) R:01160002, G:01160001, B:01160000
(1:1) R:01160005, G:01160004, B:01160003

 

 

주소값 01160000 부터 0116000D 까지 선형적으로 저장되어 있다.

2차원 배열이므로 각 라인에 대한 증가량은 1씩 일정하지만,

Y값이 증가, 즉 비트맵의 ScanLine 이 새로운 값이 대입될 때 주소값이 약간 변한다.

 

00 ~ 05 까지 선형적 증가 이후, 바로 08~0D 까지로 가는 과정,

즉 06~07 이 빠져있다.

null byte padding 인가.

 

메모리상에서 이루어지는 TBitmap 에서 null byte padding 은 없다고 실험을 통해 판단된다. (당연한가..-_-)

비트맵의 크기를 10x10 으로 하고, 바탕화면의 DC를 얻어와 Bitblt 했을 때의 주소값을 출력해 본 결과,

Y 라인의 변화에 따른 주소값의 변화가 2바이트 정도가 아니라 더 큰 수치로 나왔다.






Posted by bloodguy
,