이번에 비트맵을 불러와서 Resizing 하고 다시 저장해서 확인하기 위해
비트맵 파일을 불러오고 저장하는 예제를 만들었다.
#define LOG_OUT(_x_) OutputDebugString(_x_)
#define LOG_OUT_W(_x_) OutputDebugStringW(_x_)
#define LOG_OUT_A(_x_) OutputDebugStringA(_x_)
bool LoadBmp(char* filename, byte** pImage);
bool SaveBmp(char* filename, byte* pImage, int width, int height);
int _tmain(int argc, _TCHAR* argv[])
{
byte* pLoadImage = nullptr;
LoadBmp("../Original_image.bmp", &pLoadImage);
SaveBmp("../Save_image.bmp", pLoadImage, 1920, 1080);
free(pLoadImage);
return 0;
}
bool LoadBmp(char* filename, byte** pImage)
{
FILE* fp;
// 비트맵 정보 구조체
BITMAPFILEHEADER BMFH; ///< BitMap File Header.
BITMAPINFOHEADER BMIH; ///< BitMap Info Header.
fopen_s(&fp, filename, "rb");
if (nullptr == fp)
{
LOG_OUT_A("fopen() error");
return false;
}
// 지정한 크기만큼 파일에서 읽어옴, 그리고 비트맵파일헤더에 넣어줌
fread(&BMFH, sizeof(BITMAPFILEHEADER), 1, fp);
if (BMFH.bfType != 0x4d42) // 비트맵 파일이 아니면 종료한다.
{
fclose(fp);
LOG_OUT_A("not '.bmp' file !!!");
return false;
}
fread(&BMIH, sizeof(BITMAPINFOHEADER), 1, fp); //인포헤더에 있는 크기의 정보만큼 읽어서
if (BMIH.biBitCount != 24 || BMIH.biCompression != BI_RGB) //24비트인지 체크하고, 압축이 안되어 있는지 체크를 함
{
fclose(fp);
return false;
}
INT Width = BMIH.biWidth;
INT Height = BMIH.biHeight - 1;
INT BytePerScanline = (Width * 3 + 3) & ~3; // 패딩
INT size = BMFH.bfSize;
*pImage = (BYTE*)malloc(size);
fread(*pImage, size, 1, fp); // 파일의 정보를 전부 읽어온다.
//*pImage += BytePerScanline * Height;
// FILE*을 닫음.
fclose(fp);
return true;
}
bool SaveBmp(char* filename, byte* pImage, int width, int height)
{
// DIB의 형식을 정의한다.
BITMAPINFO dib_define;
dib_define.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dib_define.bmiHeader.biWidth = width;
dib_define.bmiHeader.biHeight = height;
dib_define.bmiHeader.biPlanes = 1;
dib_define.bmiHeader.biBitCount = 24;
dib_define.bmiHeader.biCompression = BI_RGB;
dib_define.bmiHeader.biSizeImage = (((width * 24 + 31) & ~31) >> 3) * height;
dib_define.bmiHeader.biXPelsPerMeter = 0;
dib_define.bmiHeader.biYPelsPerMeter = 0;
dib_define.bmiHeader.biClrImportant = 0;
dib_define.bmiHeader.biClrUsed = 0;
// DIB 파일의 헤더 내용을 구성한다.
BITMAPFILEHEADER dib_format_layout;
ZeroMemory(&dib_format_layout, sizeof(BITMAPFILEHEADER));
dib_format_layout.bfType = *(WORD*)"BM";
dib_format_layout.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);// +dib_define.bmiHeader.biSizeImage;
dib_format_layout.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
// 파일 생성.
FILE* fp = nullptr;
fopen_s(&fp, filename, "wb");
if (nullptr == fp)
{
LOG_OUT_A("fopen() error");
return false;
}
// 생성 후 헤더 및 데이터 쓰기.
fwrite(&dib_format_layout, 1, sizeof(BITMAPFILEHEADER), fp);
fwrite(&dib_define, 1, sizeof(BITMAPINFOHEADER), fp);
fwrite(pImage, 1, dib_define.bmiHeader.biSizeImage, fp);
fclose(fp);
return true;
}
소스 코드 :
'Basic Programming > C, C++' 카테고리의 다른 글
C++ - 함수 포인터와 함수자 - 1 (0) | 2016.04.04 |
---|---|
C++ - void 포인터, 함수 포인터 (1) | 2016.04.04 |
C++ - Windows Keyboard Codes (키보드 코드) (0) | 2016.03.24 |
C++ - 메모리 단편화로인한 메모리할당 실패 재현코드 (0) | 2016.03.22 |
C++ - 메모리 단편화(Fragmentation)의 해결방법 (0) | 2016.03.21 |