Иллюстрированный самоучитель по SVGA

Рисунки, не использующие палитру. Рисунки, подготовленные в стандарте BMP.

Полноцветные (full-color) или художественные точечные компьютерные рисунки не используют палитру. Цвет каждой точки указывается в ее коде, который занимает три байта, содержащих восьмиразрядные коды базовых цветов. Обычно такие рисунки получаются путем оцифровки, например, сканирования, цветных фотографий, слайдов, картинок, видеокадров и т. п. Иногда при подготовке значков или пиктограмм различного назначения они создаются вручную с помощью графических редакторов.

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

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


Принятый в стандарте BMP способ сжатия не эффективен, поэтому образы полноцветных рисунков обычно не упакованы. Это упрощает цикл построения рисунка, но не исключает необходимости преобразования кодов точек в формат, соответствующий установленному задачей видеорежиму.

При построении полноцветных рисунков существенно изменяются подготовительные действия, поэтому мы начнем с их подробного обсуждения. Полное описание стандарта BMP приведено в приложении А данной книги. Вам лучше предварительно прочитать его, для того чтобы узнать, как производится чтение заголовка файла и анализ его основных полей. Без этого вы не сможете использовать описанную ниже подпрограмму.

Строки образа рисунка хранятся в файле в обратном порядке, т. е. первой записана последняя строка, а последней – первая. Код каждой точки занимает три байта, содержащих базовые цвета в формате bgr. Адрес начала строки в файле должен быть кратен 4, а т. к. размер строк (в байтах) кратен 3, то после обработки каждой из них может понадобиться пропустить от О до 3 байтов в файле. Специального признака, указывающего наличие дополнительных байтов в строке, не существует, поэтому надо вычислить размер строки в файле и количество "лишних" байтов. Размер строки в файле равен утроенному количеству точек в строке, округленному до значения кратного четырем. А разность между округленным и не округленным значениями равна количеству дополнительных байтов.

Способ построения рисунка

При построении рисунка небольшого размера (см. пример 7.24) мы выбирали из оперативной памяти и записывали в видеопамять строки образа рисунка в порядке их естественного расположения (в строящемся рисунке). Однако при построении таким способом большого рисунка, как уже говорилось, потребуется дополнительное позиционирование файла, что нежелательно. Пройде позиционировать строки в видеопамяти. Поэтому мы будем выбирать строки образа рисунка в том порядке, в котором они хранятся в файле, а выводить на экран снизу вверх. Первой в файле записана последняя строка, ее и надо строить первой, затем изменится адрес видеопамяти и строится предпоследняя строка и так вплоть до первой. Но при такой последовательности действий надо изменить способ вычисления адресов строк рисунка в видеопамяти.

Коррекция адресов строк

Для определения адреса начала следующей строки мы прибавляли к текущему адресу видеопамяти константу коррекции, которая вычисляет подпрограмма calloffs (см. пример 7.13) по формуле (horsize -widthrect) *bytppnt. В данном случае нас интересует адрес предыдущей строки, поэтому формулу для вычисления константы коррекции надо записать в виде (horsize + widthrect} *bytppnt и вычитать вычисленное значение из текущего адреса видеопамяти.

Объясним, почему так, а не иначе. В процессе построения строки исходный адрес видеопамяти увеличивается на widthrect*bytppnt байтов. Если текущий адрес видеопамяти уменьшить на эту величину, то получится адрес начала построенной строки. А если адрес начала текущей строки уменьшить на величину bperiine (horsize*bytppnt), то получится адрес начала предыдущей строки (см. табл. 7.4).

Есть два способа вычисления нужной нам величины. Можно составить вариант подпрограммы caiioffs, в котором вычитание заменено сложением. А можно ничего не изменять в calloffs, но перед ее вызовом указывать в регистре dx отрицательное значение переменной widthrect (ширина рисунка). Мы используем второй способ.

Адрес начала последней строки

Для построения рисунка в нужном месте экрана обычно задается адрес видеопамяти, соответствующий левой верхней точке (началу) рисунка. В данном случае построение рисунка начинается с его левой нижней точки (начало последней строки). Поэтому перед построением рисунка в подпрограмме надо вычислять адрес этой точки.

В видеопамяти начало последней строки рисунка отстоит от начала первой на (N-1)*bperiine байтов, где N – количество строк в рисунке. Следовательно, надо вычислить указанную величину, выразить ее старшую часть в единицах приращения окна видеопамяти и сложить полученный результат с адресом первой точки рисунка.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.