Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > CreateDIBSection


Автор: mrgloom 13.6.2013, 13:59
Код

BITMAPINFO bi = {0};
        bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
        bi.bmiHeader.biWidth = w;
        bi.bmiHeader.biHeight = h;
        bi.bmiHeader.biPlanes = 1;
        bi.bmiHeader.biBitCount = 32;
        bi.bmiHeader.biCompression = BI_RGB;
        bi.bmiHeader.biSizeImage = 0;

        m_hBitmap = ::CreateDIBSection( NULL, &bi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, 0 );


для маленьких изображений CreateDIBSection работает нормально, но для 8к х 9к почему то выдаёт null. причем getlasterror возвращает 0.

возможно не может выделить большой кусок памяти? но как это сдетектировать?

Автор: Alexeis 13.6.2013, 14:16
Цитата(mrgloom @  13.6.2013,  14:59 Найти цитируемый пост)
возможно не может выделить большой кусок памяти? но как это сдетектировать? 

  Попробовать создать битмап на основе "file-mapping object". Т.е. чтобы система брала память из временного файла. 

Автор: mrgloom 13.6.2013, 14:51
http://support.microsoft.com/kb/227617/en-us

вот нашел какую то невянтную статью возможно по этому поводу.

всё сводиться к фрагментации памяти.

Добавлено через 8 минут и 36 секунд
file-mapping object  это должен быть файл на диске?  т.к. у меня этого файла на диске нету(ну если только временный файл создать)

Автор: Alexeis 13.6.2013, 19:55
Цитата(mrgloom @  13.6.2013,  15:51 Найти цитируемый пост)
всё сводиться к фрагментации памяти.

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

Цитата(mrgloom @  13.6.2013,  15:51 Найти цитируемый пост)
file-mapping object  это должен быть файл на диске?  т.к. у меня этого файла на диске нету(ну если только временный файл создать) 

  Для тестов то какая разница. Создавай где угодно, а вообще можно в папке tmp создать или создать для программы папочку в APPDATA и в ней файл разместить. file-mapping - кешируется оперативкой, так что в принципе это будет работать быстро. Вероятно, в этом случае, он не будет пытаться адресовать весь битмап целиком и можно будет создавать хоть требайтные картинки. 

Автор: Earnest 14.6.2013, 06:01
Это немножко в сторону, но добавлю.
Если ты собираешься эту хрень (8к*9к) рисовать (стандартными средствами), то готовься к тормозам. Большие растры необходимо кэшировать. Например, разбить на квадратные фрагменты. Каждый фрагмент может быть готовой дибсекцией, а можно держать общий заголовок и т.д. Некоторое усложнение дает кучу выигрышей: с фрагментацией проблем практически не бывает (бывают проблемы с исчерпанием памяти, но всегда можно уйти в мэппинг), выводится на экран быстро (масштабируется, скроллингуется), доступ тоже не бог весть какая проблема... ну и т.д.

Автор: mrgloom 20.6.2013, 12:58
Цитата

Если ты собираешься эту хрень (8к*9к) рисовать (стандартными средствами), то готовься к тормозам. Большие растры необходимо кэшировать. Например, разбить на квадратные фрагменты. Каждый фрагмент может быть готовой дибсекцией, а можно держать общий заголовок и т.д. Некоторое усложнение дает кучу выигрышей: с фрагментацией проблем практически не бывает (бывают проблемы с исчерпанием памяти, но всегда можно уйти в мэппинг), выводится на экран быстро (масштабируется, скроллингуется), доступ тоже не бог весть какая проблема... ну и т.д. 


ага тормоза как раз и есть, ну это получается как раз типа гугл мапс надо делать.

кстати есть какие то готовые форматы типа как майкрософтовский HD view?

допустим я вывожу картинки разного размера на поле(получается тайлы уже одинакового размера не сделать).
какие есть правила для деления на тайлы(какого размера должен быть тайл) и сколько должно быть уровней детализации?


Цитата

file-mapping - кешируется оперативкой, так что в принципе это будет работать быстро. Вероятно, в этом случае, он не будет пытаться адресовать весь битмап целиком и можно будет создавать хоть требайтные картинки.  

так работа с созданным объектом будет простая как раньше или надо будет создавать view для просмотра\вывода какого то куска картинки и выводить всё кусками?

Автор: Earnest 21.6.2013, 06:55
Цитата(mrgloom @  20.6.2013,  13:58 Найти цитируемый пост)
допустим я вывожу картинки разного размера на поле(получается тайлы уже одинакового размера не сделать).

Почему это? Ты же исходные растры на тайлы разбиваешь, а не поле, которое показываешь. Я так понимаю, что у тебя что-то вроде внеэкранного буфера. Этот буфер должен быть размером с экран, а это не так много, можно одним куском.
Я использую всегда тайлы одного размера (512*512). В плохом случае может быть занят самый краешек, но потери памяти ничто по сравнением с упрощением кода. Что касается уровней детализации, то сколько оптимально - сказать не могу. Мне хватает 2 (1:1 и 1:8). 
Цитата(mrgloom @  20.6.2013,  13:58 Найти цитируемый пост)
 надо будет создавать view для просмотра\вывода какого то куска картинки и выводить всё кусками?

Да, конечно. Но это совсем не исключает простого доступа к такому растру. Напиши обертки типа GetPixel или GetLine, чтобы клиентский код не загромождать.

Добавлено через 3 минуты и 2 секунды
Цитата(mrgloom @  20.6.2013,  13:58 Найти цитируемый пост)
это получается как раз типа гугл мапс надо делать.

Не совсем, там отдельные файлы, а я говорю о тайлах в памяти. Я думаю, примерно такая схема используется фотошопом.

Автор: mrgloom 21.6.2013, 10:19
Цитата

Почему это? Ты же исходные растры на тайлы разбиваешь, а не поле, которое показываешь. 

Цитата

В плохом случае может быть занят самый краешек

Я как раз про это.

Цитата

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

не знаю что такое внеэкранный буфер. 
Я так и не понял, для чего служит эта дибсекция в GDI, ну допустим это Device Independent Bitmap (т.е. это "подготовленный" к выводу кусок памяти?)Занимает ли оно доп. память? Вообщем нам надо создать DIB размеров с view и скопировать туда наши картинки\ тайлы(которые попали в view)?


у меня общее поле и на нем можно передвигать картинки типа http://www.xuvtools.org/screenshots
по идее нет смысла бить на тайлы сами картинки, если только они очень большие, а надо сделать когда в поле зрения попадает много картинок, то они должны выводиться не целиком, а их уменьшенные копии(но это должен быть специальный формат, т.е. они должны быть посчитаны заранее по идее и лежать на диске)
Но тут проблема вот в чём, допустим у нас выделено N Mb памяти, понятное дело, что все картинки мы загрузить в память не можем(т.е. получается такая ситуация, когда у нас большое увеличение(например в view попадает 2 картинки) мы можем грузить картинки целиком 1:1, когда мы видим всю панораму(допустим 500 картинок) мы должны грузить уменьшенный копии(причем размер копий должен зависеть от увеличения)). А кол-во уровней как раз влияет при переходе между уровнями детализации, т.е. производиться загрузка с диска и как то надо выбрать кол-во уровней чтобы переход был плавный.

ну это если делать по серьёзному, а вообще изначально я рассматривал именно простой вариант, когда все картинки помещаются в память, но тут даже если выводить 2 картинки 3к х 4к(т.е. общее поле примерно 6к х 8к), то при их сдвигании всё тормозит и непонятно какие требования к памяти учитывая создание дибсекции (т.е. можно как то выводить картинки так чтобы только они занимали память, а не было бы какой то общей большой картинки, куда они проецируются?) 

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