2017-02-16 7 views
0

비트 맵을 사용하는 VC++ 6 프로젝트가 있습니다. 프로그래밍 방식으로 몇 가지 비트 맵을 추출하고 .bmp 파일로 저장하려고합니다..exe 파일에서 .bmp 추출.

제게 조언 해주세요.

다음은 몇 가지 단계입니다.

  1. 저는 VC++ 6 프로젝트에서 VC++ 비트 맵 편집기로 만든 비트 맵을 가지고 있습니다.
  2. .exe에서 메뉴를 클릭하겠습니다.
  3. 이 프로그램은 자체에서 모든 .BMP 파일을 추출합니다 (이미 가지고)와 관련

    ulka에게 사전에 .BMP

감사로 하드 디스크에

+1

외부 실행 파일 리소스 섹션에서 이미지를 추출 하시겠습니까? 또는 실행중인 프로그램에서 자신의 리소스에서? –

+0

바이너리에서 LoadResource, FindResource와 같은 메소드가 있습니다. https://www.codeproject.com/Articles/4221/Adding-and-extracting-binary-resources를 참조하십시오. – sameerkn

+0

질문을 편집하여 [지금까지 시도한 내용] (http://whathaveyoutried.com)을 표시하십시오. . 문제가있는 코드의 [mcve]를 포함시켜야 특정 문제를 해결할 수 있습니다. 또한 [ask]를 읽어야합니다. –

답변

4

비트 맵 리소스를 절약 할 수 실행 파일에서 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