Yoksel: Блог/2008?/07?/18?/DIBСекции ...
SourceForge.net Logo

Home Page | Изменения / НовыеКомментарии / Справка / Помочь проекту | Вход:  Пароль:  

Блог

DIB-секции


В Windows существует два вида растров: аппаратно зависимые (DDB – Device Dependent Bitmaps) и DIB (Device Independent Bitmaps).


DDB полностью определяется драйвером устройства (экрана). Его формат никак не стандартизуется и полностью определяется драйвером. Поэтому, хоть в Windows и есть возможность получить доступ к массиву пикселов DDB, на практике эта возможность бесполезна и может быть использована разве что в отладочных целях. Также DDB должен быть обязательно совместим с контекстом устройства, на котором выполняется отрисовка. Например, можно создать DDB с требуемым количеством бит на пиксел, но не факт, что его удастся выбрать в требуемом контексте устройства. Другая проблема DDB – память, в которой они располагаются. DDB хранятся в выгружаемой памяти ядра. В результате объем, доступный для DDB, невелик и DDB расходует общую с другими процессами память. Именно эта проблема приводила к невозможности сохранять при помощи Йокселя документы, больше 4–6 страниц А4 в некоторых ОС.


DIB – это просто формат растров, независимых от конкретного устройства и ОС. BMP-файлы – это обычные DIB-растры с небольшим заголовком. Формат DIB определяет формат заголовков, палитры и массива пикселов. В Windows есть несколько функций для работы с растрами DIB, позволящие вывести в контекст устройства DIB-растр или сконвертировать DDB в DIB. Но эти функции в моем случае не интересны. Проблему «больших документов» позволяют решить DIB-секции.


DIB-секция это гибрид DIB-растра и GDI-объекта. С одной стороны DIB-секция выглядит как обычный растр – ее можно выбирать в контексте устройства и рисовать на ней как на обычном DDB. С другой стороны данные DIB-растра предоставляются самим приложением. При создании DIB-секции приложение предоставляет заголовки, палитру и, возможно, память под массив пикселов. Если приложение не предоставляет память под массив пикселов, Windows сама выделяет память из памяти приложения. Как видно память для DIB-секций выделяется не из пула ядра, а из памяти приложения. Это и позволяет обрабатывать растры бОльших размеров, чем в случае DDB.


Также DIB-секции могут быть в произвольном формате (например, с использованием нужного количества бит на пиксел).


DIB-секция создается функцией CreateDIBSection. Эта функция возвращает обычный HBITMAP, который можно выбрать в нужном контексте устройства. После этого любые операции рисования приводят к изменению массива пикселов, к которому у приложения есть прямой доступ. В теории, во всяком случае. Первоначальный вариант работы с DIB-секциями:


Данный вариант хорошо работает с не очень большими изображениями. Как только размер изображения перерастает некоторый предел, то CreateDIBSection начинает завершаться с ошибкой. Эксперименты показали, что если не вызывать MapViewOfFile или после ее вызова вызвать UnmapViewOfFile, то DIB-секция нормально создается и отрисовка на ней работает. Однако, если после отрисовки вызвать MapViewOfFile, то она тоже завершиться с ошибкой. При этом можно даже удалить контекст устройства и созданный HBITMAP – ситуацию это не изменит. Вот такой он подлый, этот Виндовс, создать дает, отрисовать дает, а вот забрать кровно нарисованное – хрен.


Пришлось изменить алгоритм на примерно следующий:


Вот тогда оно начинает работать как надо.


Правда, совсем большие документы все равно не удастся отрисовать. Но это и не требуется. Т.к. уже на определенном объеме документов начинаются проблемы:


Поэтому, не стоит отрисовывать графическим конвертером Йокселя очень большие документы. Нужно либо ограничиться небольшими/средними документами (несколько десятков страниц А4 для количества бит на пиксел 24), либо разбивать конвертацию на несколько страниц. Для любителей создавать универсальные системы отправки документов по почте, могу предложить следующий вариант использования конвертера:


Ссылок на эту страницу нет


 
Файлов нет. [Показать файлы/форму]
Комментариев нет. [Показать комментарии/форму]