Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Win API


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / WinAPI

Выпуск № 418
от 22.04.2007, 13:35

Администратор:Калашников О.А.
В рассылке:Подписчиков: 411, Экспертов: 54
В номере:Вопросов: 1, Ответов: 1


Вопрос № 82944: Добрый день. Тут столкнулся с проблемкой при работе с битмапами. Мне надо получить биты битмапа из HBITMAP. Кроме функции GetDIBits ничего не нашел... (а загружать с помощью GetPixel цвета себе дороже). Об изображении изначально ничего неизвестно...

Вопрос № 82.944
Добрый день.
Тут столкнулся с проблемкой при работе с битмапами. Мне надо получить биты битмапа из HBITMAP. Кроме функции GetDIBits ничего не нашел... (а загружать с помощью GetPixel цвета себе дороже). Об изображении изначально ничего неизвестно, поэтому получаем о нем инфу:
BITMAPINFO bmpi = {};
bmpi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
if(GetDIBits(GetWindowDC(0), bitmap, 0, 0, NULL, &bmpi, DIB_RGB_COLORS) == 0){ //Ошибка
}
Тут все работает норм, он заполняет структуру. Теперь пытаемся получить биты:
char* buffer = new char[BitmapInfo.bV5SizeImage];
if(GetDIBits(GetWindowDC(0), bitmap, 0, BitmapInfo.bV5Height, (void*)buffer, &bmpi, DIB_RGB_COLORS) == 0){/*Ошибка*/}
Запускаю. В итоге получаю сообщение следующего содержания: Run-Time Check Failure #2 - Stack Around the variable 'bmpi' was corrupted. (при выходе из функции, естественно). В режиме Debug смотрю: биты он загрузил нормально, все в порядке, но вот только переменная bmpi, которую он теоретически не должен трогать вообще, почему-то изменила содержание. Как функция WinAPI могла испортить переменную bmpi? Или я все-таки что-то не так сделал?

Приложение:

Отправлен: 17.04.2007, 13:10
Вопрос задал: Mystic (статус: 6-ой класс)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 5)

Отвечает: Gremlin
Здравствуйте, Mystic!

Во первых, не правильно используется функция GetDIBits, первый её параметр должен содержать девайс, в который выбран битмап(второй параметр).

Во вторых, использование такого кода вообще недопустимо:
GetDIBits(GetWindowDC(0), ...)
Функции GetWindowDC должна вызываться парная ей ReleaseDC

В третьих, буфер, заполняемый GetDIBits, должен быть достаточно большой, чтобы вместить все линии(scan-lines) битмапа, это довольно просто посчитать:

bits_per_line = width*bpp;

dwords_per_line = bits_per_line/32;

if(bits_per_line%32){
dwords_per_line++;
}

bytes_per_line = dwords_per_line*4;

где
width - ширина битмапа в пикселах
bpp - количество бит на пиксел(1, 4, 8, 16, 24 или 32, в зависимости от формата битмапа)

теперь размер буфера можно считать равным lines*bytes_per_line байт, где lines - это четвертый параметр функции GetDIBits

Run-Time Check Failure #2 - Stack Around the variable 'bmpi' was corrupted - эта ошибка говорит о том, что в переменную 'bmpi', расположенную в стеке была произведена несанкционированная запись. В данном случае это, скорее всего значит, что bmpi не BITMAPINFO, а нечто меньшее, т.е. здесь следует обратить внимание на biSize и число битов на пиксел: если оно не равно 24 или 32, то GetDIBits считает, что после заголовка должна идти таблица цветов, определяемая членом biClrUsed и biClrImportant.
Ответ отправил: Gremlin (статус: 2-ой класс)
Ответ отправлен: 17.04.2007, 19:44
Оценка за ответ: 4
Комментарий оценки:
Читаем МСДН:
1)GetWindowDC(0) возвращает хэндл окна приложения.
2)Буфер выделяется в достаточном объеме (функция даже все нормально возвращает)
Проблема только в том, что функция почему-то портит переменную при втором вызове. В общем, все правильно вроде


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2007, Портал RusFAQ.ru, Россия, Москва.
Авторское право: ООО "Мастер-Эксперт Про"
Email: support@rusfaq.ru, тел.: +7 (926) 535-23-31
Авторские права | Реклама на портале
Версия системы: 4.50 (beta) от 15.04.2007
Яндекс Rambler's Top100

В избранное