bitmap 이미지를 배열 형태의 c/c++ header로 만드는 소스
이미지 디코더도 없고, RTOS가 사용된 프로세서에서 GUI구성을 위해 만들었던
소스다.
24bit bitmap 파일을 읽어 이미지 부분을 아래와 같은 형태로 만들어준다.
unsigned short icon_joystick[] = { 48, 48,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000,
... 중략 ...
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000,
0x0000, 0x0000, 0x0000, 0x0000 };
배열의 첫번째와 두번째 데이터는 이미지의 width, height다.
이미지의 픽셀 데이터는 RGB16형태로 저장했다.
[사용법]
> bmp2header [bmp file path] ...
bmp 파일은 여러개 사용가능하다.
실행하면 icon.h이 생성된다.
[source code]
/*=========================================================
INCLUDE
=========================================================*/
#include <stdio.h>
#include <stdarg.h>
#include <tchar.h>
#include <Windows.h>
#include <atlstr.h>
/*=========================================================
DEFINE
=========================================================*/
#ifndef safe_free
#define safe_free(x) if(x){free(x);x=NULL;}
#endif
#ifndef RGB565
#define RGB565(R,G,B)
(((R>>3)<<11)+((G>>2)<<5)+(B>>3))
#endif
#define codetext_max_len 512
typedef struct _bmp2bin_ctx_t
{
/* icon header file
*/
HANDLE hHeaderFile;
char code[codetext_max_len];
/* bitmap file
*/
HANDLE hBMPFile;
DWORD dwBMPFileSize;
DWORD dwBMPFileSizeHigh;
BITMAPINFO *bmi;
BYTE *bmp;
}bmp2bin_ctx_t;
/*=========================================================
=========================================================*/
int OpenHeaderFile(bmp2bin_ctx_t *ctx);
int CloseHeaderFile(bmp2bin_ctx_t *ctx);
int OpenBitMapFile(bmp2bin_ctx_t *ctx, _TCHAR* filepath);
int CloseBitMapFile(bmp2bin_ctx_t *ctx);
int ConvertBitMapToHeader(bmp2bin_ctx_t *ctx, _TCHAR* filepath, BOOL
bInverse);
void bmp2bin_deinit(bmp2bin_ctx_t *ctx);
bmp2bin_ctx_t *bmp2bin_init();
/*=========================================================
=========================================================*/
int OpenBitMapFile(bmp2bin_ctx_t *ctx, _TCHAR* filepath)
{
DWORD dwReadLen;
if (!ctx || !filepath) return
-1;
if (ctx->hBMPFile)
{
CloseBitMapFile(ctx);
}
// open file
ctx->hBMPFile =
CreateFile(filepath, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (ctx->hBMPFile == NULL ||
ctx->hBMPFile == INVALID_HANDLE_VALUE)
{
printf("err : %S open fail \n",
filepath);
ctx->hBMPFile = NULL;
return -1;
}
// get file size
ctx->dwBMPFileSize =
GetFileSize(ctx->hBMPFile, &ctx->dwBMPFileSizeHigh);
if (!ctx->dwBMPFileSize)
{
printf("err : please confirm %S
\n", filepath);
return -1;
}
// alloc bitmap buffer..
ctx->bmp =
(BYTE*)malloc(ctx->dwBMPFileSize);
if (!ctx->bmp)
{
return -1;
}
// read bitmap file
ReadFile(ctx->hBMPFile,
ctx->bmp, ctx->dwBMPFileSize, &dwReadLen, NULL);
ctx->bmi =
(BITMAPINFO*)(&ctx->bmp[14]);
return 1;
}
int ConvertBitMapToHeader(bmp2bin_ctx_t *ctx, _TCHAR* filepath, BOOL
bInverse)
{
CString Name = TEXT("");
DWORD dwWriteLen = 0;
int pixelindex = 0;
int rawcnt = 0;
BYTE R, G, B;
unsigned short rgb16;
int widthcnt = 0;
int widthbytemax = 0;
int paddingcnt = 0;
if (!ctx || !filepath)
return -1;
Name = filepath;
Name.Delete(Name.GetLength() -
4, 4);
pixelindex = 14 +
sizeof(BITMAPINFOHEADER);
sprintf_s(ctx->code,
codetext_max_len, "unsigned short icon_%S[] = { %d, %d, \r\n\0",
Name.GetBuffer(), ctx->bmi->bmiHeader.biWidth,
ctx->bmi->bmiHeader.biHeight);
widthbytemax =
ctx->bmi->bmiHeader.biWidth * 3;
paddingcnt = (((widthbytemax +
3) / 4) * 4) - widthbytemax;
widthcnt = 0;
WriteFile(ctx->hHeaderFile,
ctx->code, strlen(ctx->code), &dwWriteLen, NULL);
while (ctx->dwBMPFileSize
> pixelindex)
{
B = ctx->bmp[pixelindex++];
G = ctx->bmp[pixelindex++];
R = ctx->bmp[pixelindex++];
widthcnt++;
if (widthcnt >=
ctx->bmi->bmiHeader.biWidth)
{
widthcnt = 0;
pixelindex += paddingcnt;
}
rgb16 = RGB565(R, G, B);
if (ctx->dwBMPFileSize >
pixelindex)
{
sprintf_s(ctx->code,
codetext_max_len, "0x%04X, \0", rgb16);
}
else
{
sprintf_s(ctx->code,
codetext_max_len, "0x%04X \0", rgb16);
}
WriteFile(ctx->hHeaderFile,
ctx->code, strlen(ctx->code), &dwWriteLen, NULL);
rawcnt++;
if (rawcnt >= 10)
{
sprintf_s(ctx->code,
codetext_max_len, "\r\n\0");
WriteFile(ctx->hHeaderFile,
ctx->code, strlen(ctx->code), &dwWriteLen, NULL);
rawcnt = 0;
}
}
sprintf_s(ctx->code,
codetext_max_len, "}; \r\n\r\n\r\n\0");
WriteFile(ctx->hHeaderFile,
ctx->code, strlen(ctx->code), &dwWriteLen, NULL);
return 0;
}
int CloseBitMapFile(bmp2bin_ctx_t *ctx)
{
if (!ctx) return -1;
ctx->dwBMPFileSize = 0;
ctx->dwBMPFileSizeHigh = 0;
ctx->bmi = NULL;
safe_free(ctx->bmp);
if (ctx->hBMPFile)
{
CloseHandle(ctx->hBMPFile);
ctx->hBMPFile = NULL;
}
return 1;
}
int OpenHeaderFile(bmp2bin_ctx_t *ctx)
{
DWORD dwWriteLen = 0;
ctx->hHeaderFile =
CreateFile(TEXT("icon.h"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (!ctx->hHeaderFile ||
ctx->hHeaderFile == INVALID_HANDLE_VALUE)
{
printf("err: Create header
fail\n");
ctx->hHeaderFile = NULL;
return -1;
}
sprintf_s(ctx->code,
codetext_max_len, "#ifndef __ICON_H__\r\n#define __ICON_H__\r\n\r\n\0");
WriteFile(ctx->hHeaderFile,
ctx->code, strlen(ctx->code), &dwWriteLen, NULL);
return 0;
}
int CloseHeaderFile(bmp2bin_ctx_t *ctx)
{
DWORD dwWriteLen;
if (ctx->hHeaderFile)
{
sprintf_s(ctx->code,
codetext_max_len, "#endif\r\n\0");
WriteFile(ctx->hHeaderFile,
ctx->code, strlen(ctx->code), &dwWriteLen, NULL);
CloseHandle(ctx->hHeaderFile);
ctx->hHeaderFile = NULL;
}
return 0;
}
bmp2bin_ctx_t *bmp2bin_init()
{
bmp2bin_ctx_t *ctx = NULL;
ctx =
(bmp2bin_ctx_t*)malloc(sizeof(bmp2bin_ctx_t));
if (ctx)
{
memset(ctx, 0,
sizeof(bmp2bin_ctx_t));
if (OpenHeaderFile(ctx) < 0)
{
bmp2bin_deinit(ctx);
return NULL;
}
}
return ctx;
}
void bmp2bin_deinit(bmp2bin_ctx_t *ctx)
{
if (ctx)
{
if (ctx->hBMPFile)
{
CloseBitMapFile(ctx);
}
CloseHeaderFile(ctx);
safe_free(ctx);
}
}
/*=========================================================
main
=========================================================*/
void printusage()
{
printf("usage : bmp2header [bmp
file path] ...\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
int bmpcnt = argc - 1;
int inparamindex = 1;
bmp2bin_ctx_t *ctx = NULL;
if (bmpcnt <= 0)
{
printf("err : wrong param\n");
printusage();
return 0;
}
ctx = bmp2bin_init();
if (!ctx)
{
return 0;
}
while (bmpcnt>0)
{
if (OpenBitMapFile(ctx,
argv[inparamindex])<0)
{
bmp2bin_deinit(ctx);
return 0;
}
ConvertBitMapToHeader(ctx,
argv[inparamindex],TRUE);
CloseBitMapFile(ctx);
inparamindex++;
bmpcnt--;
}
bmp2bin_deinit(ctx);
printf("done \n");
return 0;
}
댓글
댓글 쓰기