2017-02-16 8 views
0

У меня есть проект в VC++ 6 с использованием растровых изображений. Я хочу извлечь несколько растровых изображений программно и сохранить как .bmp-файл.Извлечение .bmp из .exe-файла

, пожалуйста, дайте мне несколько советов.

Это несколько шагов, которые я хочу сделать.

  1. У меня есть проект в VC++ 6 с некоторыми растровыми изображениями, которые были сделаны мной в редакторе растровых изображений VC++.
  2. Я нажму на меню в .exe.
  3. Программа извлекает все файлы .bmp из себя (это уже есть) и сохранять их на жестком диске в качестве .bmp

Заранее спасибо приветов

ULKA

+1

Вы хотите извлечь изображения из раздела ресурсов внешних исполняемых файлов? Или из ваших собственных ресурсов в запущенной программе? –

+0

Существуют такие методы, как LoadResource, FindResource из двоичного кода. См. Https://www.codeproject.com/Articles/4221/Adding-and-extracting-binary-resources – sameerkn

+0

. Пожалуйста, отредактируйте свой вопрос, чтобы показать [то, что вы пробовали до сих пор] (http://whathaveyoutried.com) , Вы должны включить [mcve] кода, с которым у вас возникают проблемы, тогда мы можем попытаться помочь с конкретной проблемой. Вы также должны прочитать [ask]. –

ответ

4

A растрового ресурс в исполняемом файле - только битмап-файл с отключенным BITMAPFILEHEADER. См. Также: https://blogs.msdn.microsoft.com/oldnewthing/20091211-00/?p=15693

Так что вам нужно создать этот заголовок самостоятельно и сначала записать его в файл. Это относительно легко для большинства распространенных растровых изображений 24 бит/с, но немного более активно, если вы хотите поддерживать другие битовые глубины.

Далее следует записать данные, полученные через вызовы FindResource()/LoadResource()/LockResource().

Пример кода (протестировано с 1 бит, 4 BPP, 8 БПП и 24 BPP растровых изображений):

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; 
} 

Edit:

Мой первоначальный ответ пропустил один важный бит (в буквальном смысле), то является флагом ios::binary для встроенного конструктора. Вот почему код не работал для Arthur G.

Так почему же это действительно работало для меня, даже без флага? Смешно, что он работал только потому, что у моего тестового растрового изображения не было никаких байтов со значением 10 (никогда не доверяйте программисту, проверяющему его собственный код)!

Одна вещь, которая может произойти по умолчанию, состоит в том, что окончание строк будет преобразовано в соответствии с платформой по умолчанию. То есть «\ n» (код ASCII = 10) будет преобразован в «\ r \ n» на платформе Windows. Конечно, это полностью испортит данные растрового изображения, так как любая реальная растровая карта, скорее всего, будет содержать это значение где-нибудь.

Таким образом, мы должны прямо указать потоку, что наши данные не должны быть запутаны, что и делает ios :: двоичный флаг.

Edit 2:

Просто для удовольствия я протянул мой пример, чтобы правильно работать на 1-бит, 4-х и 8-бит на пиксель растровые изображения тоже. Это немного более активно, потому что для этих битовых глубин матрица пикселей не запускается сразу после BITMAPINFOHEADER. Прежде, чем в пиксельный массив появится таблица цветов, размер которой должен быть добавлен к BITMAPFILEHEADER::bfOffBits.

В соответствии с MSDN, вопросы еще более сложны, потому что даже если глубина бит равна 16 или больше, может быть добавлена ​​дополнительная таблица цветов («для оптимизации производительности цветовых палитр системы» - что бы это ни значило)! См https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx (под «biClrUsed»)

Так вместо обертывание мою голову вокруг всех грязных деталей, когда и как используется таблица цветов, я просто вычислить BITMAPFILEHEADER::bfOffBits путем вычитания размера массива пикселей от общего размер ресурса (который уже известен).

Вычисление размера массива пикселей довольно просто, но вы должны следить за тем, чтобы ширина в байтах округлялась до следующего кратного 4 (один DWORD). В противном случае вы получите сообщение об ошибке при сохранении растровых изображений ширина которых в байтах не кратно 4.

Bonus чтения

Википедия имеет довольно подробнейшее описание формата файла растрового изображения с хорошей схемой из Структура: https://en.wikipedia.org/wiki/BMP_file_format

 Смежные вопросы

  • Нет связанных вопросов^_^