Что то тяжко с графикой в винде

Тема в разделе "WASM.WIN32", создана пользователем Exception13, 24 июн 2006.

  1. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Пытаюсь переучиться с DOS'а на Windows, проблемы возникли буквально сразу - вывод изображения на экран.

    Что было легко реализовать в досе, почему то стало нереализуемым в винде:

    Задача следующая:

    есть массив данных - изображение, которое может быть представлено не только в 32 битной форме, но и в любой другой из существующих, даже с палитрой.

    Причем порядок строк - человеческий: сверху вниз, а не как в DIB.

    Смотрел много примеров, в основном практикуют нечто вроде:

    CreteDIBitmap(...);

    CreateCompatibleDC(...);

    SelectObject(&bitmap);

    BitBlt(...);

    но, данный вариант не устраивает, т.к. сжирается очень много памяти, за счет того, что исходное изображение сперва конвертируется в формат пригодный для вывода в текущем видеорежиме. И исходное изображение должно быть представлено в виде DIB, т.е. с перевернутыми порядком строк, что крайне не удобно при работе с таким форматом данных.

    Потом, при каждом изменении исходного изображения необходимо вызывать CreteDIBitmap, и только потом BitBlt - перетаскивание данных из пустого в порожнее.

    Как сделать по человечески, а не через ж... т.е. исходный массив сразу отправить на DC ?



    P.S. из за подобных задрочек начинаешь все больше ненавидеть Win32.
     
  2. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Exception13

    Для создания картинки используй CreateDIBSection, эта функция может выделить необходимое количество памяти, и вернуть на неё указатель, через который туда можно записать всё что угодно.

    Для изменения порядка строк можно в структуре описывающей заголовок изображения можно указать отрицательный вертикальный размер.
     
  3. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Спасибо за ответ тов. Black_mirror, все замечательно сработало.

    Только одно теперь не пойму: если эту память за меня кто то выделяет, то кто её удалит, обычным free() - не получается, чувствуется еще одна фича win32, в которой самостоятельно разобраться не получится.
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Читайте в msdn описания функций, которые используются в коде.

    Для каждой из функций, создающей в памяти какие-либо объекты, есть функции, удаляющие эти объекты.
     
  5. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    Спасибо конечно за ссылку.

    Я прекрасно осведомлен о том, что на свете существует MSDN, но проблема в том, что достать его нет возможности. Выкачать на модемном соединении сами понимаете - нереально. Есть только справочник по API функциям, да и тот на русском, из которого мало что понятно.

    Именно по этому и обратился на форум.

    Огромное спасибо тов. cresta за ответ в стиле RTFM.
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    msdn доставать необязательно. Он всегда есть в онлайне, и совершенно бесплатно. Более того, совсем не обязательно выкачивать весь msdn.

    Достаточно открыть страницу http://msdn.microsoft.com и в окошке поиска набрать CreateCompatibleDC. После чего нажать "Go" и получить ссылку на страницу с описанием функции.

    Так что, rtfm. Больше тут нечего сказать.
     
  7. NaZGuL

    NaZGuL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    41
    Адрес:
    Russia
    Exception13

    Я в англицком не силен, так что сам переведи:

    ___MSDN___

    Remarks

    As noted above, if hSection is NULL, the system allocates memory for the device-independent bitmap. The system closes the handle to that memory when you later delete the device-independent bitmap by calling the DeleteObject function. If hSection is not NULL, you must close the hSection memory handle yourself after calling DeleteObject to delete the bitmap.
     
  8. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Придется учить англицкий, как же ты собираешься программировать? Не так уж и плохо владеть несколькими языками!
     
  9. mix_mix

    mix_mix Михаил

    Публикаций:
    0
    Регистрация:
    8 окт 2005
    Сообщения:
    277
    Адрес:
    Токио
    NaZGuL

    Если hSection равен нулю, тогда система сама выделить память под картинку, которая, затем будет автоматически освобождена, если в hSection лежит адрес памяти, то картинка будет находится там.

    crypto

    Это правда, без этого будет очень сложно.
     
  10. NaZGuL

    NaZGuL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    41
    Адрес:
    Russia
    crypto,mix_mix, мне пока и этого хватает! Общий смысл понятен и ладно :) Но все равно я над этим подумаю.

    mix_mix, ты забыл сказать про самое главное, чтобы удалить из памяти нужно удалить bitmap, а затем вызвать DeleteObject... (вроде так)
     
  11. mix_mix

    mix_mix Михаил

    Публикаций:
    0
    Регистрация:
    8 окт 2005
    Сообщения:
    277
    Адрес:
    Токио
    NaZGuL

    Наоборот :)

    Вначале удаляешь bitmap, а затем освобождаешь hSection функцией CloseHandle.
     
  12. Exception13

    Exception13 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    66
    Адрес:
    Владимир
    О как !, сколько тонкостей, тут чувствуется не как в DOSe твори что хочешь, а еще и последовательность важна :)

    С битмапом на силу разобрался, конечно крайне непонравилось то что функция CreateDIBSection сама выделяет память, вот если бы я самостаятельно мог её выделять, а потом подсунуть указатель в эту функцию - это было бы гораздо прямее.

    А вот что делать с палитрой, интересно.

    Если её подсунуть вместе со структурой BITMAPINFO в CrateDIBSection, то все отображается как надо. Теперь встает задача изменить палитру, делаю следующие действия:

    hPal = CreatePalette(...)

    SelectPalette(hDC,hPal,FALSE)

    RealizePalette(hDC)

    в результате чего меняется только часть палитры, причем RealizePalette возвращает 0.

    Если же при создании битмапа в функции CreateDIBSection установить параметр iUsage = DIB_PAL_COLORS и, соответственно не передавать в структуре BITMAPINFO информацию о палитре, а задать её самому вышеперечисленными функциями, то - в итоге получается нераскрашеная черная картинка.

    В чем может быть косяк ?

    Основные мои предположения в том что используется 32 битный CompatibleDC, и он не поддерживает работу с палитрой, но почему все функции работы с палитрой возвращают ненулевые значения, кроме RealizePalette.

    Как-нибудь можно решить вопрос с установкой палитры для текущего битмапа?
     
  13. NaZGuL

    NaZGuL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2004
    Сообщения:
    41
    Адрес:
    Russia
    Exception13, может попробовать SetDIBColorTable.

    В MSDN пишут про нее что она должна устанавливать палитру для DIB.



    PS: Заодно может глянеш тут?
     
  14. YoungBastard

    YoungBastard New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2005
    Сообщения:
    231
    Адрес:
    Russia
    Exception13

    кароче, все в винде ништяк!!!
    открываешь gdi+ в msdn и читаешь. Там то, что тебе нужно делается в три строчки
    когда-то писал, но уже не помню ничего.
    все там очень просто делается и не загоняйся с gdi, это уже в прошлом!
    На rsdn.ru есть отличные примеры как работать с gdi+. И реализация работы BitBlt (не помню как там все это называется) там на много приятней, т.к. там все на ООП и ты можешь пользоваться этими удобствами.
     
  15. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Многие современные адаптеры не поддерживают операции с палитрой! API GetDeviceCaps может подтвердить это. Косвенно это ограничение обычно обходят через StretchDIBits или по-ламерски, т.е. прямо через массив RGB пиксельными функциями.