Практика программирования (Бейсик, Си, Паскаль)

Работа с отдельными точками и растровыми изображениями


Вывод отдельных точек (пикселов) в программе имеет смысл, когда количество таких точек сравнительно невелико (от нескольких десятков до 2—3 тысяч). Если мы попытаемся заполнить весь экран путем вывода каждой точки, то эта процедура займет достаточно много времени. Для изменения кода цвета пиксела достаточно указать его координаты (оконные или экранные) и задать новый цвет.

В QBasic для этой цели используется один из двух операторов PSET или PRESET:

PSET х,у [,c] . PRESET x,y [,с]

Третий параметр является необязательным, но если он задан, то определяет новый код цвета. Если в этих операторах цвет не задавать, то оператор PSET использует цвет переднего плана, PRESET — цвет фона. Таким образом, один из них рисует точку, а второй — стирает ее на экране. Если очень надо, то программа может узнать цвет пиксела с заданными координатами. В QBasic для этой цели используется функция P0INT:

c=P0INT(x,y)

Аналогичные возможности присутствуют и в библиотеке BGI:

ТС: putpixel(х,у,с);

ТР: PutPixei(x,у,с);

c=getpixel (х, у) ;

c:=-GetPixel (x, у) ;

Гораздо больший интерес представляют процедуры группового копирования кодов цвета пикселов, заполняющих прямоугольную область экрана и образующих растровое изображение. Так как операция копирования между байтами видеопамяти и оперативной памяти выполняется достаточно быстро, то таким способом можно мгновенно обновить содержимое экрана. Правда, целиком скопировать или обновить содержимое экрана нельзя по совершенно тривиальной причине. В таком обмене должен участвовать массив, а в наших системах программирования размер массива не может превышать 64 Кбайт. Тогда как для запоминания кодов цвета всех пикселов экрана потребуется не менее чем 640x480x4/8 = 153 600 байт. Поэтому для полного обновления содержимого экрана необходимо не менее трех обращений к соответствующей процедуре.

В системе QBasic групповой обмен с видеопамятью осуществляют операторы GET И PUT:

GET (xl,yl)-(x2,y2), А% PUT (хЗ,уЗ), А%, ovr



Координаты двух точек, как и всегда, определяют положение левого верхнего (xl.yl) и правого нижнего (х2,у2) углов копируемой, прямоугольной области экрана. Коды цветности пикселов, попадающих в этот участок, переписываются в массив А%, который должен иметь достаточный объем. В самых первых элементах массива А% запоминаются габариты сохраняемой области экрана — число строк и число столбцов, вслед за которыми в каждый байт массива А% поступают коды цветности двух смежных пикселов. Если оказывается, что число пикселов в строке нечетно, то прихватывается код цветности еще одного лишнего пиксела, чтобы сохранить байтовую структуру данных.




Так как при копировании области экрана в оперативной памяти сохраняются не только цвета пикселов, но и размеры запоминаемой области, то в операторе PUT достаточно указать только одну точку на экране, начиная с которой будет размещаться восстанавливаемое изображение. Параметр ovr определяет способ взаимодействия кодов цветности налагаемых пикселов с их прежними цветовыми атрибутами. 0н может принимать одно из следующих мнемонических значений:

  • PSET — новый код цветности вытесняет предыдущий;

  • PRESET — инвертированное значение нового кода цветности заменяет предыдущий код;

  • AND — новый и старый коды цветности поразрядно логически умножаются; П 0R — новый и старый коды цветности поразрядно логически складываются;

  • X0R — над новым и старым кодами выполняется операция "исключающее ИЛИ" (другими словами — выполняется поразрядное сложение по модулю 2).

    Абсолютно те же функции в BGI-пакете выполняют процедуры getimage и

    putimage:

    getimage(x1, y1,x2,y2,A);

    putimage(x3,x4,A,ovr);

    Единственное отличие заключается в мнемонике значений параметра ovr:

    ТС: C0PY_PUT TP: CopyPut QBasic: PSET N0T_PUT NotPut PRESET

    AND_PUT AndPut AND

    0R_PUT 0rPut 0R

    X0R_PUT XorPut X0R

    В BGI-пакете предусмотрена еще одна функция, с помощью которой можно определить размер массива А в байтах до выполнения операции getimage:

    size=imagesize(xl,yl,x2,y2);

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




    Содержание раздела