Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > SetDIBits не срабатывает


Автор: deniska 31.8.2006, 10:23
Функции SetDIBits, SetBitmapBits, SetDIBitsToDevice
не срабатывают при увеличении размера рисунка. Может сработат, а может и нет, причем вернет 0 и она и GetLastError. Почему такая нестабильность? Кто-нибудь с таким сталкивался?

Автор: Earnest 31.8.2006, 10:36
Что значит - не срабатывает?

Автор: deniska 31.8.2006, 10:55
Это значит что возвращает 0

Автор: GremlinProg 31.8.2006, 12:30
да, бывало такое, что SetDIBitsToDevice иногда не заполняло девайс. Выбрал альтернативу - рендеринг IPicture.

Автор: deniska 31.8.2006, 12:36
не пойдеть smile  мне нужно максимально быстро заполнять dc. Да и потом СОМ этот.....

Автор: GremlinProg 31.8.2006, 12:45
так что лучше, скорость или надежность? На некоторых виндовозах SetDIBitsToDevice вообще отказывался работать, возможно тут аппаратная зависимость: мне приходилось рендерить на довольно ёмкие девайсы

Автор: deniska 31.8.2006, 13:06
Нет, ну должно же быть какое-то нормальное объяснение почему несрабатывает.
Честно говоря первый раз столкнулся с фигней. Всегда думал что на АПИ писать надежнее smile

Добавлено @ 13:08 
В конце концов IPicture в итоге теми же ф-циями пользуется. Наверно.....

Автор: GremlinProg 31.8.2006, 14:40
IPicture, канешн теми же, видимо есть где-то проблема, которую IPicture обходит, потому что я досканально все проверил, уповал на адрес(его варавнивание), дак нет, не в нем дело, все параметры просчитывал, в принципе использую RGBQUAD, поэтому проблем с выравниванием каждой строки на границе слова у мя не было, но это тоже необходимо учитывать, проверь это дело у себя.

Автор: Earnest 31.8.2006, 16:21
А вместо них нельзя использовать BitBlt со товарищи? Никогда не встречалась с их "не-срабатываниями". Да, несколько другие исходные данные: 2 контекста, а не растр + контекст, но это вообще не проблема.
В чем специфика задачи, что нужно именно SetDIBits? Блиттинг работает не медленнее... Кстати, функции IPicture. скорее всего, как раз на блиттингах реализованы.

Автор: GremlinProg 31.8.2006, 18:28
Earnest, а доступ к растру прикажешь GetPixel'ом организовывать? )) Очевидно же, что необходим прямой доступ.

Добавлено @ 18:33 
IPicture организует диб-образ в вирт. памяти(это можно проверить GetObject'ом), следовательно дамп образа мэпируется в граф. девайс напрямую, а SetDIBits, по крайней мере, это делает. Вывод: IPicture скорее всего опирается на SetDIBits и ей подобные.

Автор: Earnest 1.9.2006, 06:50
А кто против? Заведи DIB-секцию, и будет и прямой доступ, и возможность выбора в контекст.
DIB-растр в DIB-секцию элементарно превращается.

Добавлено @ 06:52 
Кстати, работа с контекстами (и DIB-секцией) хороша еще тем, что автоматически получаешь возможность растризовать любые векторные примитивы - GDI рисует...

Автор: GremlinProg 1.9.2006, 08:15
Earnest, а в чем, собственно, проблема? Я вроде как о DIB-секции и говорю. В этом и преимущество IPicture. Только секция создается сразу, без лишних вопросов. Это экономит кучу времени.

Автор: Earnest 1.9.2006, 09:38
IPicture, как бы оно не реализовывалась, это обертка вокруг API, т.е. есть какие-никакие лишние издержки. Я не знаю, почему автор не хочет IPicture. Может, GDI+ не хочет подключать. Поэтому и предлагаю АПИшную альтернативу функциям SetDIBits и пр., которая всегда работает - я, по крайней мере, не сталкивалась с косяками блиттинга. Хотя не исключено, что у него просто косяки в коде. 

Автор: GremlinProg 1.9.2006, 09:51
GDI+ тут совершенно ни при чем (может путаешь с оберткой CPicture). Ему просто не хочется связываться с OLE, как он уже успел заметить (хотя, на мой взгляд, это не должно быть так обременительно, как например тот же GDI+, которому нужна таки библиотека. OLE поддерживается везде и уже давно)

Добавлено @ 10:03 
Альтернатива, конечно, всегда есть. Можно использовать и CreateDIBSection, но, если необходимо загрузить в эту секцию растр из файла любого из зарегистрированных в системе граф. типов (jpeg, bmp, tif...), то я все же порекомендовал бы IPicture.

Автор: Earnest 1.9.2006, 10:52
Да, пожалуй, спутала...
Не... OLE никому не порекомендую - уж там-то издержки...
Лучше тогда CImage использовать (GDI+ ИМХО, лучше чем OLE). А класс простой. 


Автор: deniska 1.9.2006, 11:01
Цитата

Хотя не исключено, что у него просто косяки в коде smile 

 smile 
Может, может. Сейчас вот сижу капаюсь.
BitBlt я пробовал. С него собственно и начал.
Функции возвращают 0 при увеличении картинки где-то с 500*500
У меня в окне есть область которая заполняется фоном с градиентом. Эту область я мышой могу ресайзить. Пока размер области небольшой, все вроде работает

Автор: GremlinProg 1.9.2006, 11:40
Цитата(Earnest @  1.9.2006,  12:52 Найти цитируемый пост)
OLE никому не порекомендую - уж там-то издержки...

Конечно, не все OLE-компоненты универсальны и удобны, но не нужно судить так обо всех интерфейсах , я тоже сталкивался с некоторыми излишествами в OLE, но мы сейчас говорим конкретно об одном:
Цитата(MSDN)

IPicture Methods:
get_Handle Returns the Windows GDI handle of the picture managed within this picture object. 
get_hPal Returns a copy of the palette currently used by the picture object. 
get_Type Returns the current type of the picture. 
get_Width Returns the current width of the picture in the picture object. 
get_Height Returns the current height of the picture in the picture object. 
Render Draws the specified portion of the picture onto the specified device context, positioned at the specified location. 
set_hPal Sets the current palette of the picture. 
get_CurDC Returns the current device context into which this picture is selected. 
SelectPicture Selects a bitmap picture into a given device context, returning the device context in which the picture was previously selected as well as the picture's GDI handle. 
get_KeepOriginalFormat Returns the current value of the picture object's KeepOriginalFormat property. 
put_KeepOriginalFormat Sets the picture object's KeepOriginalFormat property. 
PictureChanged Notifies the picture object that its picture resource changed. 
SaveAsFile Saves the picture's data into a stream in the same format that it would save itself into a file. 
get_Attributes Returns the current set of the picture's bit attributes. 

Здесь get_Handle возвращает HBITMAP, с которым можно работать как обычно, а метод Render делает очень полезную вещь: рендерит в указанный девайс любой кусок HBITMAP, с нужным масштабом, причем метод рендеринга выбирается тот, который поддерживается системой: если это битмап, то происходит нечто похожее на StretchDIBits, если упакованный жипех, то его собственный рендеринг. Т.е. Render избавляет нас от лишней мороки, да и о качестве говорить не приходится. Остальные методы, роли не играют, они просто дублируют соответствующие вызовы API, так что нагрузки особой на ресурсы не несут.

Автор: Earnest 1.9.2006, 12:10
Цитата(deniska @  1.9.2006,  12:01 Найти цитируемый пост)
BitBlt я пробовал. С него собственно и начал.
Функции возвращают 0 при увеличении картинки где-то с 500*500

Так может у тебя с преобразованием координат какая-то ерунда?
Там же есть ограничения... Или еще что-то в этом роде...

Покажи кусок кода.

Добавлено @ 12:12 
Я думаю, что в этом случае ни IPicture, ни CImage тебя не спасут... нужно разобраться с координатами

Автор: deniska 1.9.2006, 12:51
Цитата

Так может у тебя с преобразованием координат какая-то ерунда?

Я думаю не должно так как при небольших то размерах работает нормально а координаты считаются одинаково для любого размера.
Мне этими функциями приходилось пользоваться так как градиент я ручками делал (массив заполнял).
потом этот массив надо было в dc записывать.
Сейчас попробовал FillGradient. Сижу и наслаждаюсь: в 3 раза быстрее, никаких глюков с прорисовкой,
про память под массив париться не нужно. В общем пока одни достоинства.
Спасибо Earnest и GremlinProg что пытались помочь
P.S. Все равно странно почему же глюковало? Надо руки выпрямлять наверно....

Автор: Earnest 1.9.2006, 12:59
Цитата(deniska @  1.9.2006,  13:51 Найти цитируемый пост)
Я думаю не должно так как при небольших то размерах работает нормально а координаты считаются одинаково для любого размера

Существуют ограничения

Автор: GremlinProg 1.9.2006, 14:18
Цитата(Earnest @  1.9.2006,  14:10 Найти цитируемый пост)
Я думаю, что в этом случае ни IPicture, ни CImage тебя не спасут

однако же IPicture как раз и спасло, я уже говорил )
Цитата(deniska @  1.9.2006,  14:51 Найти цитируемый пост)
так как градиент я ручками делал (массив заполнял).

Лучше всего сразу о таких вещах сообщать, т.е. говорить не так, мол не работает функция, а сразу пояснять задачу и цели, тогда тебя будет проще понять. Действительно, специализированные функции, такие как AlphaBlend, BitBlt, StretchBlt, FillGradient и т.п. как правило работают намного быстрее, нежели их пытаться реализовать, пусть даже через прямой доступ. Прямой доступ к растру лучше использовать только когда необходимо применить к нему какой-то собственный алгоритм, который не имеет аналогов в API, либо когда нужен попиксельный анализ растра.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)