Главная » Ассемблер, Железо » Масштабирование изображений

0

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

Чтобы увеличить изображение без искажений, достаточно просто увеличить в N раз каждую его точку, то есть представить ее в виде квадрата NxN точек. Недостаток такого способа заключается в том, что сильно проявляет себя «лестничный эффект» — становится очень заметной ступенчатость изображения. Пример двукратного увеличения изображения текстового символа показан на рис. 4.13.

Рис. 4.13. Увеличение размера изображения символа в два раза

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

Чтобы сжать изображение в целое число раз, нужно вычислить среднюю яркость квадрата из NxN точек и округлить ее до ближайшего

доступного значения яркости. Однако такое округление приводит к сильным искажениям при выводе черно-белого изображения (рис. 4.14, слева).

Рис. 4.14. Сжатие изображения в два раза различными способами

Другой простой способ сжатия — вычеркивание. В этом случае сохраняются лишь одна из N последовательно расположенных строк и одна из N колонок, а остальные зачеркиваются (рис. 4.14, справа). Основной недостаток данного способа состоит в том, что тонкие вертикальные и горизонтальные линии могут быть полностью потеряны: в приведенном примере таким образом стерта перекладина у буквы А.

Программа ShowFont, предназначенная для просмотра в увеличенном масштабе символов шрифта, извлеченного из знакогенератора видеоконтроллера, приведена в листинге 4.13. Программа использует две вспомогательные процедуры:

•       процедура ShowRusFont отображает на экран шрифт в виде таблицы в масштабе 1:1 — каждому биту маски соответствует на экране один пиксел;

•       процедура ShowLargeChar осуществляет вывод символа в верхней части экрана (по центру) в увеличенном масштабе — каждому биту маски соответствует на экране квадрат размером 8×8 пикселов.

Листинг 4.13. Просмотр символов шрифта 8×16 в графическом режиме в увеличенном масштабе

IDEAL

Р386

LOCALS

MODEL MEDIUM

; Код видеорежииа 640×480, 256 цветов, с линейной

; адресацией видеобуфера

Листинг 4.13 (продолжение)

GraphicsMode equ 4101h

; Логическая ширина строки в пикселах Logi calStri ngLength equ 1024

; Ширина экрана в пикселах ScreenLength equ 640

; Высота экрана, строк ScreenHeigth equ 480

; Подключить файл нненонических обозначений : кодов управляющих клавиш и цветовых кодов

Include "listl_03.inc"

; Подключить файл макросов

Include "listl_04.inc"

DATASEG

; Нонер строки "активного" синвола ActiveCharString DW ?

; Номер колонки "активного" символа ActiveCharColumn DW ? : Текстовые сообщения

Text

DB 10,13,"Выберите символ для проснотра "

DB "в увеличенном насштабе:",0

DB 25,14,"Для выбора символа в таблице "

DB "используйте управляющие",0

DB 26,14,"клавиши: ‘",18h,"’,’",19h

DB "’,"’,lAh,"’, ‘",lBh,"’.",0 PEsc

DB 29,20,"Для выхода из програнны нажмите ESC",0 ENDS

SEGMENT sseg para stack ‘STACK’

DB 400h DUP(?)

ENDS

CODESEG

;* Основной модуль программы *

• А А А1 А’ Л’ А’ ‘к А А’ Л’ А А А1 А’ ‘к А А’ Л’ А А’ Л’ ‘А’ А Л1 Л А А А Л1

PROC ShowFont

mov АХ,DGROUP

mov DS,AX

mov [CS:MainDataSeg],AX

; Установить текстовый режин

mov AX,3 int lOh : Установить режим прямой адресации паняти

call Initialization

; "Захватить" текстовый шрифт

cal1 GrabRusFont

; Установить видеорежин

call SetVESAVideoMode : Отобразить текстовые сообщения

; Установить черный цвет фона

mov [DefaultBackground],BLACK

; Установить зеленый цвет текста

mov [Defaulted or], LIGHTGREEN MGShowText 3,Text

; Установить желтый цвет текста

mov [Defaulted or], YELLOW MGShowString PEsc : Инициализировать перененные

mov [ActiveCharString].0

mov [ActiveCharColumn],0

; ОСНОВНОЙ ЦИКЛ

@@GetCommand:

; Отобразить шрифт

cal1 ShowRusFont

; Отобразить укрупненно "активный" Символ

call ShowLargeChar

; Ввести конанду

cal1 GetChar

cmp AL,0;введена конанда?

jne

@@Error

; Проанализировать код конанды и выполнить

; соответствующую операцию

cmp AH,B_Esc ;"Выход"

je

@@End

@@TestBS:

cmp AH,B_BS ;"Стрелка влево" jne

@@TestFWD

; Проверить значение нонера колонки

; (нининально допустимое значение – 0) cmp [ActiveCharColumn].0

je

@@Error

; Уменьшить нонер колонки dec [ActiveCharColumn]

jmp short

@@GetCoirniand

@@TestFWD:

cmp AH.BFWD ;"Стрелка вправо" jne

@@TestUp

: Проверить значение нонера колонки

; (наксинально допустимое значение – 31) cmp [Acti veCharColumn],31 jae

@@Error

; Увеличить нонер колонки

inc [ActiveCharColumn]

jmp short

@@GetConmand (aOTestUp:

cmp AH.BJJP :"Стрелка вверх" jne

@@TestDn

Листинг 4.13 (продолжение)

: Проверить значение ноиера строки : (иинииально допустииое значение – 0) cmp [ActiveCharString],0

je

@@Error : Уменьшить номер строки dec [ActiveCharString]

jmp short

@@GetCommand

@@TestDn:

cmp AH,B_DN :"Стрелка вниз" jne

@@Error

; Проверить значение номера строки

; (максимально допустимое значение – 7) cmp [ActiveCharString],7 jae

@@Error

; Увеличить номер строки

inc [ActiveCharString]

jmp short

@@GetCommand

@@Error:

; Нврная команда – подать звуковой сигнал

cal1 Веер

jmp @0GetCommand

; ВЫХОД ИЗ ПРОГРАММЫ

@@End:

; Установить текстовый режим

mov АХ.З int 10h

; Выход в DOS

mov AH,4Ch int 21h ENDP ShowFont

;* ОТОБРАЗИТЬ ШРИФТ В ВИДЕ ТАБЛИЦЫ * ;* Параметры передаются через переменные * ;* ActiveCharString и ActiveCharColumn *

PROC ShowRusFont near pushad

mov SI,offset Font8xl6

mov EDI,[Li nearVi deoBuffer]

add EDI,LogicalStringLength*200+64+4

mov [FontString],0 @йпО: : Отобразить очередную строку символов

mov [FontColumn],0

@@ml: : Отобразить очередной символ

mov АН,16 :число строк (байт) в маске символа

mov DL.0 ;цвет фона символа

mov DH.7 ;цвет символа

mov СХ,[Acti veCharStri ng] cmp [FontString],CX jne (a@m2

mov CX.[ActiveCharColumn] cmp [FontColumn],CX jne

@@m2

mov DL.l ;цвет фона "активного" синвола

mov DH.15 ;цвет "активного" синвола

@@т2:

; Отобразить строку изображения символа

mov AL.[SI] загрузить очередной байт маски символа

mov СХ.В

@ftn3: : вывести на экран очередную точку изображения символа rol AL.1 jc

@@m4

mov [byte ptr GS:EDI],DL

jmp short @®m5

@@m4:

mov [byte ptr GS:EDI],DH

@@пб:

inc EDI loop

@@m3

inc SI

add EDI,Logi calStri ngLength-8 dec AH jnz

@@m2

sub EDI,LogicalStringLength*16-16

inc [FontColumn] cmp [FontColumn],32 jb P@ml

add EDI,Logi calStri ngLength*24-32*16

inc [FontString]

cmp [FontString],8

jb РйпО

popad

ret

ENDP ShowRusFont

;* ОТОБРАЗИТЬ СИМВОЛ В УВЕЛИЧЕННОМ МАСШТАБЕ (В:1) * ;* Номер отображаемого символа определяется * ;* переменными ActiveCharString и ActiveCharColumn *

PROC ShowLargeChar near pushad

: Отобразить символ сверху, по центру экрана

mov EDI,[LinearVideoBuffer]

add EDI.(640-64)/2 : Вычислить положение маски символа в массиве шрифта

; Загрузить указатель на шрифт

mov SI,offset FontBxl6

; Умножить номер строки на 32

mov АХ,[Acti veCharStri ng]

Листинг 4.13 (продолжение) shl АХ.5

; Прибавить ноиер колонки

add AX.[ActiveCharColumn]

; Умножить на размер символа в байтах (на 16)

shl АХ.4

add SI. АХ

; Отобразить,символ в масштабе 8:1 (размер точки

; символа – 8×8 точек экрана)

mov DX.16 :высота маски символа в точках @ftnl:

mov АН.8 :строку символа повторить 8 раз @йп2: ;Отображаем строку символа

mov AL, [SI] Прочитать байт маски

mov СХ.8 :ширина маски символа в точках

@@m3: rol AL.1 jc

@@т4

•.Отобразить 8 точек синего цвета

mov [dword ptr GS:EDI].01010101h

add EDI,4

mov [dword ptr GS:EDI],01010101h

jmp short

@@m5 "

@@m4: ;Отобразить 8 точек желтого цвета

mov [dword ptr GS:EDI].OEOEOEOEh

add EDI.4

mov [dword ptr GS:EDI],OEOEOEOEh

@@m5:

add EDI,4 loop

@@m3

; Перейти на следующую строку изображения символа

add EDI,LogicalStringLength-64 dec АН jnz

@@m2

; Перейти на следующую строку маски символа

inc SI

dec DX

jnz <a@ml

popad

ret

ENDP ShowLargeChar ENDS

: Подключить процедуры ввода данных и вывода на экран

; в текстовом режиме

Include "listl_02.inc"

; Подключить подпрограмму, переводящую сегментный : регистр GS в режим линейной адресации

Include "list2_01.inc"

; Подключить набор процедур общего назначения,

; предназначенных для установки графических : видеорежимов и работы в них

include "list4_02.inc"

; Подключить набор процедур вывода текста,

; предназначенных для 256-цветных режимов

Include "list4_03.inc"

END

Источник: Кулаков В. К90 Программирование на аппаратном уровне: специальный справочник (+дискета). 2-е издание. — СПб.: Питер, 2003. — 847 е.: ил.

По теме:

  • Комментарии