비트 맵 리소스를 절약 할 수 실행 파일에서 BITMAPFILEHEADER가 제거 된 비트 맵 파일입니다. 다음을 참조하십시오. https://blogs.msdn.microsoft.com/oldnewthing/20091211-00/?p=15693
그래서이 헤더를 직접 작성하여 파일에 쓰십시오. 가장 일반적인 24 bpp 비트 맵은 상대적으로 쉽지만 다른 비트 심도를 지원하려는 경우 조금 복잡합니다.
다음은 FindResource()/LoadResource()/LockResource() 호출을 통해 얻은 데이터를 씁니다.
int main()
{
// Obtain a handle to the current executable
HMODULE hInst = ::GetModuleHandle(nullptr);
// Locate and load a bitmap resource of the executable
if(HRSRC hr = ::FindResource(hInst, MAKEINTRESOURCE(IDB_BITMAP1), RT_BITMAP))
if(HGLOBAL hg = ::LoadResource(hInst, hr))
if(auto pData = reinterpret_cast<const char*>(::LockResource(hg)))
{
DWORD resourceSize = ::SizeofResource(hInst, hr);
// Check if we safely read the complete BITMAPINFOHEADER
// (to prevent a GPF in case the resource data is corrupt).
if(resourceSize >= sizeof(BITMAPINFOHEADER))
{
auto& bmih = reinterpret_cast<const BITMAPINFOHEADER&>(*pData);
// For simplicitly we can only save uncompressed bitmaps.
if(bmih.biCompression == BI_RGB)
{
// Calculate the size of the bitmap pixels in bytes.
// We use this to calculate BITMAPFILEHEADER::bfOffBits correctly.
// This is much easier than calculating the size of the color table.
DWORD widthBytes = (bmih.biBitCount * bmih.biWidth + 31)/32 * 4;
DWORD heightAbs = abs(bmih.biHeight); // height can be negative for a top-down bitmap!
DWORD pixelSizeBytes = widthBytes * heightAbs;
// Create the bitmap file header.
BITMAPFILEHEADER bfh = { 0 };
bfh.bfType = 0x4D42; // magic bytes: "BM"
bfh.bfSize = sizeof(bfh) + resourceSize; // total file size
bfh.bfOffBits = bfh.bfSize - pixelSizeBytes; // offset to bitmap pixels
// Write file header and bitmap resource data to file.
std::ofstream of("mybitmap1.bmp", std::ios::binary);
of.write(reinterpret_cast<const char*>(&bfh), sizeof(bfh));
of.write(pData, resourceSize);
}
}
}
return 0;
}
편집 : 내 원래의 대답은 하나의 중요한 비트 (문자 그대로) 놓친
, 그
코드 예제 (1 BPP, 4 BPP, 8 BPP, 24 BPP 비트 맵 테스트) ofstream 생성자에 대한 ios::binary
플래그입니다. 그렇기 때문에 Arthur G의 코드가 작동하지 않습니다.
그런데 플래그가 없는데도 실제로 실제로 작동 했나요? 재밌는 점은 내 테스트 비트 맵에 값이 10 인 바이트가 없기 때문에 (프로그래머가 자신의 코드를 테스트하는 것을 신뢰하지 않기 때문에) 효과가 있었다는 것입니다.
기본적으로 발생할 수있는 한 가지 점은 행의 종료가 플랫폼 기본값에 따라 변환된다는 것입니다. 즉, '\ n'(ASCII 코드 = 10)은 Windows 플랫폼에서 "\ r \ n"으로 변환됩니다. 물론 실제 비트 맵은이 값을 어딘가에 포함하기 때문에 비트 맵 데이터를 완전히 엉망으로 만듭니다.
그래서 우리는 ofstream에 우리의 데이터가 엉망이되어서는 안된다는 것을 분명히 말해야합니다. 이것은 정확하게 ios :: binary 플래그가하는 것입니다.
편집 2 : 내가 1 비트에 대해 제대로 작동하려면 내 예를 확장 그냥 재미를 위해
는 4 비트 및 픽셀 당 8 비트도 비트 맵. 비트 심도가 BITMAPINFOHEADER 바로 다음에 픽셀 배열이 시작되지 않기 때문에 조금 더 복잡합니다. 픽셀 배열은 색상 표가 나오기 전에 크기가 BITMAPFILEHEADER::bfOffBits
에 추가되어야합니다.
MSDN에 따르면 비트 깊이가 16 이상인 경우에도 옵션 색상 표 ("시스템 색상 표의 성능 최적화"- 의미하는대로)가있을 수 있으므로 문제가 더욱 복잡해집니다! 전체에서 픽셀 배열의 크기를 빼서 ("biClrUsed"아래)
그래서 대신 색상 표 사용 방법, 나는 단순히 BITMAPFILEHEADER::bfOffBits
을 계산할 때 모든 더러운 세부 사항의 주위에 내 머리를 포장을 https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx보기 자원 크기 (이미 알려져 있음).
픽셀 배열의 크기를 계산하는 것은 매우 간단하지만 바이트 단위로 너비를 4의 다음 배수 (1 DWORD)로 반올림해야합니다. 바이트 그 폭이 4
보너스의 배수가 아닌 비트 맵을 저장할 때 그렇지 않으면 오류를 얻을 것이다 읽을
위키 백과의 멋진 다이어그램 비트 맵 파일 형식의 꽤 깊이있는 설명이 구조 : https://en.wikipedia.org/wiki/BMP_file_format
외부 실행 파일 리소스 섹션에서 이미지를 추출 하시겠습니까? 또는 실행중인 프로그램에서 자신의 리소스에서? –
바이너리에서 LoadResource, FindResource와 같은 메소드가 있습니다. https://www.codeproject.com/Articles/4221/Adding-and-extracting-binary-resources를 참조하십시오. – sameerkn
질문을 편집하여 [지금까지 시도한 내용] (http://whathaveyoutried.com)을 표시하십시오. . 문제가있는 코드의 [mcve]를 포함시켜야 특정 문제를 해결할 수 있습니다. 또한 [ask]를 읽어야합니다. –