BMP 파일을 직접 억세스 하시는 것은 솔직히 별로 추천해 드리고 싶지는 않네요.
헤더 파일이 포토샵도, 그림판도 각각의 프로그램마다 조금씩 틀려지고, 가로 세로 좌표가
홀수, 짝수인지에 따라서도 구조체가 변경됩니다.
가장 쉬운 방법은 Image등에서 LoadFromFile 하신후, Canvas->Pixels[x][y] 하셔서 컬러를
뽑아내는 방식입니다. 하지만, 이 것은 속도가 매우 느린 연산으로 수십개 컬러를 뽑아내는데는
효과적인지만, 전체 컬러를 다 뽑아내는 것에는 별로 효과적인 방법은 아닙니다.
두번째 방법으로는 ScanLine으로 읽어오는 방법인데, 메모리처럼 BMP 파일을 접근합니다.
그 예제는 아래 게시물을 참고하시기 바랍니다
http://www.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=18840
세번째 방법으로는 구리구리님이 말씀하신 것처럼 파일 자체 내에서 읽어들이는 방법인데,
아래와 같이 진행할 수가 있겠습니다. 아래는 제가 TGA 파일을 읽으려고 썼던 방식인데,
TGA 파일과 BMP 파일이 틀린점은, BMP는 RGB, TGA는 RGBA 로 1Byte(32Bit 컬러 기준)만 더
읽는다는 차이 밖에 없습니다.
부디 성공하시길.
cuperido
void __fastcall TAlphaImage::LoadTGAFromFile(AnsiString stFilename)
{
std::auto_ptr<TMemoryStream> BUFFER(new TMemoryStream);
RGBTRIPLE *rtColor, *rtAlphaColor;
unsigned char chTemp, chAlphaValue;
unsigned short shTemp;
int itTemp, itWidth, itHeight, itX, itY;
try {
BUFFER->Clear();
BUFFER->LoadFromFile(stFilename);
} catch(...) {
return;
}
BUFFER->Read(&shTemp, 2);
if(shTemp) return; // 특수 헤더성 TGA는 읽지 않음
BUFFER->Read(&chTemp, 1);
if(chTemp != 2) return; // True Color가 아니면 읽지 않음
BUFFER->Seek(12, soFromBeginning);
BUFFER->Read(&shTemp, 2); // Width 읽기
itWidth = shTemp;
BUFFER->Read(&shTemp, 2); // Height 읽기
itHeight = shTemp;
BUFFER->Read(&chTemp, 1);
if(chTemp != 32) return; // 32Bit Color가 아니면 읽지 않음
BUFFER->Read(&chTemp, 1);
if(chTemp != 8) return; // Alpha Channel이 없거나 8 Bit가 넘으면 읽지 않음
// Image 설정
Width = itWidth;
Height = itHeight;
Picture->Bitmap->Width = itWidth;
Picture->Bitmap->Height = itWidth;
Picture->Bitmap->PixelFormat = pf24bit;
Picture_Alpha->Bitmap->Width = itWidth;
Picture_Alpha->Bitmap->Height = itWidth;
Picture_Alpha->Bitmap->PixelFormat = pf24bit;
for(itY = itHeight - 1; itY >= 0; itY --) {
rtColor = (RGBTRIPLE *)Picture->Bitmap->ScanLine[itY];
rtAlphaColor = (RGBTRIPLE *)Picture_Alpha->Bitmap->ScanLine[itY];
for(itX = 0; itX < itWidth; itX ++) {
BUFFER->Read(&rtColor->rgbtBlue, 1);
BUFFER->Read(&rtColor->rgbtGreen, 1);
BUFFER->Read(&rtColor->rgbtRed, 1);
BUFFER->Read(&chAlphaValue, 1);
rtAlphaColor->rgbtBlue = chAlphaValue;
rtAlphaColor->rgbtGreen = chAlphaValue;
rtAlphaColor->rgbtRed = chAlphaValue;
rtColor ++;
rtAlphaColor ++;
}
}
}
구리구리 님이 쓰신 글 :
:
: // 그림 영역 크기 = 그림영역 전체 크기 - 그림 비트 위치
:
: DWORD dwTemp = dwLength - bmfHeader.bfOffBits;
:
:
:
: // 그림 크기 만큼 생성을 하고요
:
: DWORD *tempBmp;
:
: tempBmp = new DWORD[dwTemp];
:
:
:
: bmfHeader.bfOffBits 크기만큼 포인터를 이동해서 그부분 부터 복사를 하면 될 것 같은데
:
: 그걸 어떻게 해야할지 모르겠네요 ㅡ.ㅡ
:
: 헤더는 제외하고 그림 데이터만 저장하려고 합니다
: