При загрузке изображения из файла, ресурса или потока класс TBitmap
обычно создает изображение в формате DIB-секции, соответствующее источнику по цветовой глубине. Исключение составляют сжатые файлы (формат BMP поддерживает сжатие только для 16- и 256-цветных изображений) — в этом случае создается DDB. В файле Graphics
определена глобальная переменная DDBsOnly
, которая по умолчанию равна False
. Если изменить ее значение на True
, загружаемое изображение всегда будет иметь формат DDB.
В справке сказано, что когда DDBsOnly = False
, вновь создаваемые изображения по умолчанию хранятся в виде DIB-секций. На самом деле из-за ошибки в модуле Graphics
(как минимум до 2007-й версии Delphi включительно) вновь созданное изображение всегда хранится как DDB независимо от значения DDBsOnly
.
Класс TBitmap
имеет свойство ScanLine
, через которое можно получить прямой доступ к массиву пикселов, составляющих изображение. В справке написано, что это свойство можно использовать только с DIB-изображениями. Но на самом деле DDB-изображения тоже позволяют использовать это свойство, хотя и с существенными ограничениями. Если изображение хранится в DDB- формате, при обращении к ScanLine
создастся его DIB-копия, и ScanLine
возвращает указатель на массив этой копии. Поэтому, во-первых, ScanLine
работает с DDB-изображениями очень медленно, а во-вторых, работает не с изображением, а с его копией, откуда вытекают следующие ограничения:
1. Копия создаётся на момент обращения к ScanLine
, поэтому изменения, сделанные на изображении с помощью GDI-функций после этого, будут недоступными.
2. Каждое обращение к ScanLine
создает новую копию изображения, а старая при этом уничтожается. Гарантии, что новая копия будет располагаться в той же области памяти, нет, поэтому указатель, полученный при предыдущем обращении к ScanLine
, больше нельзя использовать.
3. Изменения, сделанные в массиве пикселов, затрагивают только копию изображения, но само изображение при этом не меняется. Поэтому в случае DDB свойство ScanLine
дает возможность прочитать, но не изменить изображение.
Следует отметить, что TBitmap
иногда создает DIB-секции, даже если свойства HandleType
и PixelFormat
явно указывают на использование DDB. Особенно часто это наблюдается для изображений большого размера. По всей видимости, это происходит, когда в системном пуле нет места для хранения DDB-изображения такого размера, и разработчики TBitmap решили, что в таком случае лучше создать DIB-изображение, чем не создавать никакого. Пример BitmapSpeed
на прилагаемом компакт-диске позволяет сравнить скорость выполнения различных операций с DDB- и DIB-изображениями.
1.1.12. ANSI и Unicode
Windows поддерживает две кодировки: ANSI и Unicode. В кодировке ANSI (American National Standard Institute) каждый символ кодируется однобайтным кодом. Коды от 0 до 127 совпадают с кодами ASCII, коды от 128 до 255 могут означать разные символы различных языков в зависимости от выбранной кодовой страницы. Кодовые страницы позволяют уместить многочисленные символы различных языков в однобайтный код, но при этом можно работать только с одной кодовой страницей, т. е. с одним языком. Неверно выбранная кодовая страница приводит к появлению непонятных символов (в Интернете их обычно называют "кракозябрами") вместо осмысленного текста.
В кодировке Unicode используется 2 байта на символ, что даёт возможность закодировать 65 536 символов. Этого хватает для символов латиницы и кириллицы, греческого алфавита, китайских иероглифов, арабских и еврейских букв, а также многочисленных дополнительных (финансовых, математических и т. п.) символов. Кодовых страниц в Unicode нет.