리눅스에서의 raw 데이터 BMP파일로 만드는 방법..

skah2lp2의 이미지

리눅스 기반으로 할려니 어렵네요..

소스가 있거나 추천할만한 책이 있으시면..

부탁드립니다...

익명 사용자의 이미지

skah2lp2 wrote:
리눅스 기반으로 할려니 어렵네요..

소스가 있거나 추천할만한 책이 있으시면..

부탁드립니다...

RAW데이터를 BMP로 변환하는데.. 리눅스라고 어려운건 전혀 없습니다.

그럼 Windows 를 사용하신다면 어떻게 하시는지요?

LeadTools같은 상용 그래픽스 라이브러리 사용하십니까?

질문 내용을 보건데... Windows에서 프로그램 짜시는 것 같은데...
MSDN을 여셔서.. BITMAPFILEHEADER와 BITMAPINFOHEADER 구조체가 어떤건지 확인하시고... 그 구조체로 BMP파일 만드시면 됩니다.

이건 Windows, Linux뿐만 아니라.. 어떤 OS라도 같은 방법을 사용해야 합니다.

글 쓰다 보니까.. "리눅스 기반으로 할려니 어렵네요" 라는 말에 화가나서.. 좀 강하게 얘기한것 같습니다.

자세히 알려드리죠.

typedef struct tagBITMAPFILEHEADER { 
  WORD    bfType; 
  DWORD   bfSize; 
  WORD    bfReserved1; 
  WORD    bfReserved2; 
  DWORD   bfOffBits; 
} BITMAPFILEHEADER, *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, *PBITMAPINFOHEADER; 

typedef struct tagRGBQUAD {
  BYTE    rgbBlue; 
  BYTE    rgbGreen; 
  BYTE    rgbRed; 
  BYTE    rgbReserved; 
} RGBQUAD; 

위에 있는 코드가 BMFH, BMIH 의 내용입니다.
BMP파일은 BMFH, BMIH, RGBQUAD, BITMAP DATA 의 순서로 되어 있습니다.

BMFH 에는

WORD     bfType;    ->  'BM' 이 들어갑니다. 인식을 위한겁니다.
DWORD   bfSize;     -> 전체 크기가 들어갑니다.
DWORD   bfOffBits;  ->  BITMAP DATA영역의 시작  offset 이 들어갑니다.

BMIH 에는

DWORD  biSize;    -> 구조체 크기
LONG   biWidth;    -> 이미지 너비
LONG   biHeight;    -> 이미지 높이
WORD   biPlanes;   -> plane의 개수로 1을 넣으시고
WORD   biBitCount;  -> 이미지 bit depth
DWORD  biCompression;  -> 압축 안한다고 넣어야 되는데.. 0인가? 기억 안납니다.  다른 BMP읽어서 확인해 보시고...
DWORD  biSizeImage;   -> 이미지 크기(BITMAP DATA 부분만)
LONG   biXPelsPerMeter;   -> 수평방향 Dots per meter (필요없는것 같지만 중요)
LONG   biYPelsPerMeter;   -> 수직방향 Dots per meter (출력등에서 크기 맞출때 반드시 필요)
DWORD  biClrUsed;   -> 0
DWORD  biClrImportant;  -> 0

이후에 팔레트 모드인경우만 RGBQUAD로 팔렛트 나열되고...
이후에 BITMAP DATA가 위치합니다.

주의하실건 BITMAP DATA는 각 스캔라인이 4의 배수여야 합니다.
4의 배수를 맞추기 위해 모자른 만큼은 padding 영역으로 0을 넣어줘야 합니다.

simpid의 이미지

로그인 안하니까.. '손님' 이라고 나타나는군요.

답변 붙었을때 메일 받기위해 다시 남깁니다.

이해안되는거 있으면.. 다시 물어보시길...

simpid의 이미지

skah2lp2 님께서 좀더 자세한 답변 달라는 개인 메세지 주셔서 게시판에 답변 남깁니다.

혹시 비슷한 주제에 대해 논의가 또 나오지 않기 위합니다.

아래는 제가 사용하는 코드입니다.
Windows 기반이지만 Linux라고 못쓸껀 하나도 없습니다.

dibCreate()는 DIB(Windows에선 이미지를 이렇게 부릅니다. Device Independence Bitmap) 를 만들고
dibSaveBMP()로 저장할 수 있습니다.

skah2lp2 님은 320*240 의 RAW 데이터를 BMP로 저장하고 싶어하셨는데...
dibCreate()로 320*240의 이미지를 만드시고... RAW데이터를 넣고 dibSaveBMP()로 저장하시면 됩니다.

물론 내부에선 Win32 API를 사용하고 있으므로 대응되는 Linux Runtime Library 함수로 변경하시면 되겠고..

RAW 데이터를 넣을때는
dibImageBuffer()로 이미지 데이터 주소를 얻고 dibPitch()로 스캔라인 크기를 구할 수 있습니다.

그리고 dibCreate()를 사용하실때 bitCount를 8 이하로 준다면 팔레트 모드가 되어 dibPaletteBuffer()로 팔레트 주소를 얻어 적당하게 설정해 주셔야 합니다.

참고로 BMP는 y 방향이 뒤집혀 있으므로 dibImageBuffer()로 구한 주소는 가장 마지막 스캔라인이 됩니다.

#define DIB_DPM2DPI(x)	((unsigned int)(((float(x) / 100.0f) * 2.54f) + 0.5f))
#define DIB_DPI2DPM(x)	((unsigned int)(((float(x) / 2.54f) * 100.0f) + 0.5f))

#define DIB_LOCK(x)		((PBITMAPINFOHEADER)GlobalLock(x))
#define DIB_UNLOCK(x)	GlobalUnlock(x)

typedef struct tagBITMAPFILEHEADER { 
  WORD    bfType; 
  DWORD   bfSize; 
  WORD    bfReserved1; 
  WORD    bfReserved2; 
  DWORD   bfOffBits; 
} BITMAPFILEHEADER, *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, *PBITMAPINFOHEADER; 

typedef struct tagRGBQUAD { 
  BYTE    rgbBlue; 
  BYTE    rgbGreen; 
  BYTE    rgbRed; 
  BYTE    rgbReserved; 
} RGBQUAD; 

unsigned char* DIB_API dibImageBuffer(PBITMAPINFOHEADER pBMIH)
{
	return	((unsigned char*)pBMIH) + sizeof(BITMAPINFOHEADER) +	// palette buffer
			((pBMIH->biBitCount) <= 8 ? (1 << (pBMIH->biBitCount)) : 0) * sizeof(RGBQUAD);	// size palette buffer
}

RGBQUAD* DIB_API dibPaletteBuffer(PBITMAPINFOHEADER pBMIH)
{
	return (RGBQUAD*)(((char*)pBMIH) + sizeof(BITMAPINFOHEADER));
}

unsigned int DIB_API dibPitch(PBITMAPINFOHEADER pBMIH)
{
//	return (((pBMIH->biBitCount) * (pBMIH->biWidth) + 31) >> 5) << 2;
	return (((pBMIH->biWidth * pBMIH->biBitCount) + 31) & ~31) >> 3;
}

HGLOBAL DIB_API dibCreate(unsigned int width, unsigned height, unsigned int bitCount, unsigned int horizDPM, unsigned int vertDPM)
{
	HGLOBAL hDIB;
	PBITMAPINFOHEADER pBMIH;

	// check parameter
	assert(width && height);
	assert(bitCount == 1 || bitCount == 4 || bitCount == 8 || bitCount == 24);

	unsigned int pitch				= ((bitCount * width + 31) >> 5) << 2;
	unsigned int maxPalette			= bitCount <= 8 ? (1 << bitCount) : 0;
	unsigned int sizeImageBuffer	= pitch * height;
	unsigned int sizePaletteBuffer	= maxPalette * sizeof(RGBQUAD);

	// alloc new image buffer
	if((hDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(BITMAPINFOHEADER) + sizeImageBuffer + sizePaletteBuffer)) == NULL) return NULL;

	// lock memory
	if((pBMIH = DIB_LOCK(hDIB)) == NULL)
	{
		GlobalFree(hDIB);
		return NULL;
	}

	// init BITMAPINFOHEADER
	pBMIH->biSize			= sizeof(BITMAPINFOHEADER);
	pBMIH->biWidth			= width;
	pBMIH->biHeight			= height;
	pBMIH->biPlanes			= 1;
	pBMIH->biBitCount		= (WORD)bitCount;
	pBMIH->biCompression	= BI_RGB;
	pBMIH->biSizeImage		= sizeImageBuffer;
	pBMIH->biXPelsPerMeter	= horizDPM;
	pBMIH->biYPelsPerMeter	= vertDPM;
	pBMIH->biClrUsed		= 0;
	pBMIH->biClrImportant	= 0;

	DIB_UNLOCK(hDIB);

	return hDIB;
}

bool DIB_API dibSaveBMP(PBITMAPINFOHEADER pBMIH, LPCTSTR szPath)
{
	BITMAPFILEHEADER BMFH;
	DWORD dwWrite;

	// check parameters
	assert(pBMIH);
	assert(szPath);

	unsigned int pitch				= (((pBMIH->biBitCount) * (pBMIH->biWidth) + 31) >> 5) << 2;
	unsigned int maxPalette			= (pBMIH->biBitCount) <= 8 ? (1 << (pBMIH->biBitCount)) : 0;
	unsigned int sizeHeader			= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	unsigned int sizeImageBuffer	= pitch * (pBMIH->biHeight);
	unsigned int sizePaletteBuffer	= maxPalette * sizeof(RGBQUAD);

	// create BITMAPFILEHEADER
	BMFH.bfType = (WORD)(('M' << 8) | 'B');
	BMFH.bfSize = sizeHeader + sizePaletteBuffer + sizeImageBuffer;
	BMFH.bfReserved1 = 0;
	BMFH.bfReserved2 = 0;
	BMFH.bfOffBits = sizeHeader + sizePaletteBuffer;

	// create file
	HANDLE hFile = CreateFile(szPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
	if(hFile == NULL) return FALSE;

	// write header
	WriteFile(hFile, (LPCVOID)&BMFH, sizeof(BITMAPFILEHEADER), &dwWrite, NULL);
	WriteFile(hFile, (LPCVOID)pBMIH, sizeof(BITMAPINFOHEADER), &dwWrite, NULL);

	// write palette
	WriteFile(hFile, (LPCVOID)dibPaletteBuffer(pBMIH), sizePaletteBuffer, &dwWrite, NULL);

	// write bitmap
	WriteFile(hFile, (LPCVOID)dibImageBuffer(pBMIH), sizeImageBuffer, &dwWrite, NULL);

	// close file
	CloseHandle(hFile);

	return TRUE;
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.