Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Загрузка BMP 
V
    Опции темы
KAPJICOH
Дата 25.9.2007, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 18.4.2006

Репутация: нет
Всего: нет



Не могу загрузить BMP файл. Вот код:

Код

FILE* file;
fopen_s(&file, "Load.bmp", "rb");
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;

fread(&bfh, sizeof(BITMAPFILEHEADER), 1, file);
fread(&bih, sizeof(BITMAPINFOHEADER), 1, file);

BYTE* arr = new BYTE[(bih.biWidth + bih.biWidth%4) * bih.biHeight * 3];
fpos_t pos = bfh.bfOffBits;
fsetpos(file, &pos);
for(int i=0;i<(bih.biWidth + bih.biWidth%4) * bih.biHeight * 3; i++)
    fread(&arr[i], sizeof(BYTE), 1, file);

HBITMAP hbm, hOldbm;
HDC hMemDC, hDC;
BITMAP bm;
POINT  ptSize, ptOrg;

hDC = GetWindowsDC(hWnd);
hMemDC = CreateCompatibleDC(hDC);
HBITMAP hBitmap = CreateBitmap(bih.biWidth, bih.biHeight, bih.biPlanes, bih.biBitCount, arr);

 // Выбираем изображение bitmap в контекст памяти
hOldbm = (HBITMAP)SelectObject(hMemDC, hBitmap);
//ОШИБКА:  hOldbm = NULL т.е битмап не присоединился к устройству

  // Если не было ошибок, продолжаем работу
  if (hOldbm)
  {
    // Для контекста памяти устанавливаем тот же
    // режим отображения, что используется в
    // контексте отображения
    SetMapMode(hMemDC, GetMapMode(hDC));

    // Определяем размеры изображения
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);

    ptSize.x = bm.bmWidth;   // ширина
    ptSize.y = bm.bmHeight;  // высота

    // Преобразуем координаты устройства в логические
    // для устройства вывода
    DPtoLP(hDC, &ptSize, 1);

    ptOrg.x = 0;
    ptOrg.y = 0;

    // Преобразуем координаты устройства в логические
    // для контекста памяти
    DPtoLP(hMemDC, &ptOrg, 1);

    // Рисуем изображение bitmap
    BitBlt(hDC, 0, 0, ptSize.x, ptSize.y,
           hMemDC, ptOrg.x, ptOrg.y, SRCCOPY);

    // Восстанавливаем контекст памяти
    SelectObject(hMemDC, hOldbm);
  }

  // Удаляем контекст памяти
  DeleteDC(hMemDC);


    fclose(file);
    delete[] arr;


Битмап загружается, но я не могу присоединить его к устройству. Может кто-нибудь сталкивался с этой проблемой? Спасибо.
PM MAIL   Вверх
Mihhail
Дата 26.9.2007, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 13.9.2007

Репутация: 5
Всего: 9



Здесь дело в несоответствии цветовой палитры и глубины цвета, картинки и контекста. Необходимо преобразование:
Код
hDC = GetDC( hWnd );
hMemDC = CreateCompatibleDC( hDC );

//Создаём картинку совместимое с контекстом
HBITMAP hBitmap = CreateCompatibleBitmap( hDC, bih.biWidth, bih.biHeight );

// Выбираем изображение bitmap в контекст памяти
hOldbm = (HBITMAP)SelectObject( hMemDC, hBitmap );

BITMAPINFO bi;
memcpy( &bi.bmiHeader, &bih, sizeof(BITMAPINFOHEADER) );

//Устанавливаем пиксели картинки, используя цветные данные загруженой
SetDIBits( hMemDC, hBitmap, 0, (WORD)bih.biHeight, arr, &bi, DIB_RGB_COLORS );


Цитата(KAPJICOH @  26.9.2007,  01:44 Найти цитируемый пост)
for(int i=0;i<(bih.biWidth + bih.biWidth%4) * bih.biHeight * 3; i++)
    fread(&arr[i], sizeof(BYTE), 1, file);

Может проще так?
fread( arr, sizeof(BYTE), (bih.biWidth + bih.biWidth%4) * bih.biHeight * 3, file );
smile

Это сообщение отредактировал(а) Mihhail - 26.9.2007, 09:21
PM MAIL WWW   Вверх
Alexeis
Дата 26.9.2007, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



  странный метод вычисления размера растра.

Правильно будет 
   LineSize = (bih.biWidth * 3 +3) / 4 * 4;

Мы же выравниваем на 4 байта. Например, если длинна строки 257 байт, то она выравнивается на 3 байта до 260 байт

Строчка bih.biWidth + bih.biWidth%4 никак не выравнивает строку на границу 4х байт. Кроме того сам размер тоже должен быть выравнен на границу 4х байт.
   BitsSize = ((bih.biWidth * 3 +3) / 4 * 4 * bih.biHeight + 3) / 4 * 4;

Это сообщение отредактировал(а) Alexeis - 26.9.2007, 09:32


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Earnest
Дата 26.9.2007, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(Mihhail @  26.9.2007,  10:19 Найти цитируемый пост)
Может проще так?

Не проще, так как в общем случае строки bmp-файла и битмапа имеют неодинаковую длину: первые выровнены на 4 байта, а вторые - на 2.

KAPJICOH
Здесь куча мест, где можно допустить ошибку. И на форуме такие темы обсуждались, и кода примеры были, работающего. Поищи... в сто двадцать пятый раз искать в чем кривизна загрузки битмапа ей богу лень. smile 



--------------------
...
PM   Вверх
Mihhail
Дата 26.9.2007, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 13.9.2007

Репутация: 5
Всего: 9



Цитата(Earnest @  26.9.2007,  15:13 Найти цитируемый пост)
Не проще, так как в общем случае строки bmp-файла и битмапа имеют неодинаковую длину: первые выровнены на 4 байта, а вторые - на 2.

В данном случае это ни как не проявляется. Идёт побайтная загрузка всего блока растровых данных. Выравнивание учитывается позже, при вызове функции SetDIBits.
PM MAIL WWW   Вверх
KAPJICOH
Дата 26.9.2007, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 18.4.2006

Репутация: нет
Всего: нет



Цитата(Earnest @ 26.9.2007,  11:13)
KAPJICOH
Здесь куча мест, где можно допустить ошибку. И на форуме такие темы обсуждались, и кода примеры были, работающего. Поищи... в сто двадцать пятый раз искать в чем кривизна загрузки битмапа ей богу лень. smile

Сколько не искал всегда натыкался на функцию LoadBitmap.

Битмап создается, но привязать его к устройству не получается, как проверить правильность загрузки битмапа?
PM MAIL   Вверх
KAPJICOH
Дата 26.9.2007, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 18.4.2006

Репутация: нет
Всего: нет



Все основная задача - вывести на экран решена. Вот код кому интересно:
Код

FILE* file;
    fopen_s(&file, "Load.bmp", "rb");
    BITMAPFILEHEADER bfh;
    BITMAPINFOHEADER bih;

    fread(&bfh, sizeof(BITMAPFILEHEADER), 1, file);
    fread(&bih, sizeof(BITMAPINFOHEADER), 1, file);

    if(hWnd == NULL)
    {
        Create(hParent, bih.biWidth, bih.biHeight);
    }
    else
    {
        MoveWindow(hWnd, 55, 0, bih.biWidth, bih.biHeight, TRUE);
    }

    HDC hdc = GetWindowDC(hWnd);
    BITMAPINFO BMI;

    BMI.bmiHeader.biSize = sizeof(BMI.bmiHeader);
    BMI.bmiHeader.biBitCount = bih.biBitCount;
    BMI.bmiHeader.biCompression = BI_RGB;
    BMI.bmiHeader.biPlanes = 1;
    BMI.bmiHeader.biWidth = bih.biWidth;
    BMI.bmiHeader.biHeight = bih.biHeight;

    BYTE* arr = new BYTE[((bih.biWidth * 3 +3) / 4 * 4 * bih.biHeight + 3) / 4 * 4];
    fpos_t pos = bfh.bfOffBits;
    fsetpos(file, &pos);
    fread(arr, sizeof(BYTE), ((bih.biWidth * 3 +3) / 4 * 4 * bih.biHeight + 3) / 4 * 4, file);

    //Выводим... Если есть hBitmap, можно обойтись SetDIBits
    SetDIBitsToDevice(hdc, 0, 0, bih.biWidth, bih.biHeight, 0, 0, 0, bih.biHeight, arr, &BMI, DIB_RGB_COLORS);

    fclose(file);
    delete[] arr;


Всем спасибо!
PM MAIL   Вверх
Alexeis
Дата 26.9.2007, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(KAPJICOH @  26.9.2007,  13:37 Найти цитируемый пост)
Сколько не искал всегда натыкался на функцию LoadBitmap.

  А как же LoadImage()? Она как раз грузит битмап из файла и создает битмап.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
KAPJICOH
Дата 26.9.2007, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 18.4.2006

Репутация: нет
Всего: нет



Цитата(Alexeis @ 26.9.2007,  15:44)
  А как же LoadImage()? Она как раз грузит битмап из файла и создает битмап.

По условию надо все это делать самому. Наверное я само задание криво объяснил))
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1263 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.