비트맵(.bmp) 파일 구조
2022. 1. 6. 16:22ㆍC++
비트맵의 파일구조는 아래와 같다.
BitmapFileHeader |
BitmapInfoHeader |
이미지 데이터 |
BitmapFileHeader와 BitmapInfoHeader의 구조
typedef struct tagBITMAPFILEHEADER {
WORD bfType; //파일의 타입. 문자 BM이 저장된다.
DWORD bfSize; //파일의 사이즈
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits; //bitmap bits(실제 이미지 데이터)가 시작되는 지점
} BITMAPFILEHEADER, *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, * LPBITMAPINFOHEADER, * PBITMAPINFOHEADER;
파일의 규격에 있어서는 신기하게도 구조체의 패딩 규칙이 적용되지 않는다. (pragma pack)
따라서 BITMAPFILEHEADER의 크기는 14 Byte, BITMAPINFOHEADER의 크기는 40 Byte가 된다.
이 두가지 구조체 이후에 실제 이미지 데이터가 들어가게 된다.
이미지 데이터는 상하반전된 상태로 들어간다.
이러한 헤더를 이용하여 알파블렌딩을 구현해보자.
sample.bmp와 sample2.bmp의 이미지데이터를 반씩 섞어서, 두 이미지가 마치 섞인 것 처럼 보이게된다.
코드에서 BITMAPFILEHEADER의 bfOffBits를 이용하여 이미지 데이터가 시작되는 부분을 찾고,
그 이후의 데이터를 반씩 합쳐서 알파블렌딩을 구현했다.
#include <iostream>
int main()
{
//이미지 파일 두 개 읽어오기
FILE* fp1;
FILE* fp2;
unsigned char* s1;
unsigned char* s2;
int fileSize;
int dataStartPosition;
fopen_s(&fp1, "sample.bmp", "rb");
fopen_s(&fp2, "sample2.bmp", "rb");
if (fp1 == nullptr || fp2 == nullptr)
exit(1);
//파일 내부의 헤더 두개와 비트 malloc으로 저장하기
//크기 구하기
fseek(fp1, 0, SEEK_END);
fileSize = ftell(fp1);
fseek(fp1, 0, SEEK_SET);
//할당
s1 = (unsigned char*)malloc(fileSize);
s2 = (unsigned char*)malloc(fileSize);
if (s1 == nullptr || s2 == nullptr)
exit(1);
//파일 통째로 저장
fread_s(s1, fileSize, 1, fileSize, fp1);
fread_s(s2, fileSize, 1, fileSize, fp2);
//읽기 끝내기
fclose(fp1);
fclose(fp2);
//헤더가 어디서부터 어디까지인지 가져오기 -> 비트맵파일헤더 offset값으로
dataStartPosition = s1[10];
//s1에다가 결과값 저장 : 헤더는 그대로 넣고 내용은 절반씩 더해서 넣기
for (int i = dataStartPosition; i < fileSize; i++)
{
s1[i] = (s1[i] >> 1) + (s2[i] >> 1);
}
//이미지 파일 생성
fopen_s(&fp1, "alpha.bmp", "wb");
if (fp1 == nullptr) exit(1);
//파일에 작성
fwrite(s1, 1, fileSize, fp1);
//종료
fclose(fp1);
return 0;
}
'C++' 카테고리의 다른 글
[C++] 형 변환 연산 (0) | 2022.01.07 |
---|---|
C++ 정리 (0) | 2022.01.06 |
[C/C++] 파일 패킹 (0) | 2022.01.06 |
[C/C++] 파일 입출력 (0) | 2022.01.06 |
C언어 문자열 처리 (0) | 2022.01.06 |