Wyswietlanie obrazkow BMP
Autor: Bogdan Drozdowski, bogdandr (at) op.pl
Jesli przejrzeliscie moj poprzedni kurs zwiazany z grafika, to umiecie juz
cos samodzielnie narysowac.
Ale przeciez w Internecie (i nie tylko) jest tyle ciekawych rysunkow, nie
mowiac juz o tych, ktore moglibyscie stworzyc dla jakiegos specjalnego celu,
np. swojej wlasnej gry. Dlatego teraz pokaze, jak takie rysunki wyswietlac.
Ze wzgledu na prostote formatu, wybralem pliki typu BMP. Plik, ktory chcecie
wyswietlic powinien miec rozmiar 320x200 pikseli w 256 kolorach (jak
pamietamy, taki rysunek pasuje jak ulal do trybu graficznego 13h).
Wszystkie operacje na pliku zostaly juz przez mnie szczegolowo opisane w
jednej z czesci mojego kursu, wiec tutaj nie bedziemy poswiecac im zbyt
wiele uwagi.
Ale przejdzmy wreszcie do interesujacych nas szczegolow.
Powinniscie zaopatrzyc sie w cokolwiek, co opisuje format BMP. Informacje,
z ktorych bede tutaj korzystal, znalazlem w Internecie (niestety, nie
pamietam juz gdzie, ale mozecie poszukac na http://www.wotsit.org/).
A oto naglowek pliku BMP (skladnia jezyka Pascal niestety):
--------------------------------------------
Autor tekstu: Piotr Sokolowski, 6 maja 1998r
Budowa naglowka pliku BMP:
Type
TBitMapHeader =
Record
bfType : Word; (dwa bajty)
bfSize : LongInt; (cztery bajty)
bfReserved : LongInt;
bfOffBits : LongInt;
biSize : LongInt;
biWidth : LongInt;
biHeight : LongInt;
biPlanes : Word;
biBitCount : Word;
biCompression : LongInt;
biSizeImage : LongInt;
biXPelsPerMeter : LongInt;
biYPelsPerMeter : LongInt;
biClrUsed : LongInt;
biClrImportant : LongInt;
End;
Gdzie:
bftype - jest to dwubajtowa sygnatura "BM"
bfsize - czterobajtowy rozmiar pliku
bfreserved - pole zarezerwowane(0)
bfoffbits - przesuniecie poczatku danych graficznych
bisize - podaje rozmiar naglowka
biwidth - wysokosc bitmapy w pikselach
biheight - szerokosc bitmapy w pikselach
biplanes - liczba pitplanow(prawie zawsze ma wartosc 1)
bibitcound - ilosc bitow na piksel. Przyjmuje wartosc 1,4,8 lub 24.
bicompression - sposob kompresji
bisizeimag - rozmiar obrazka w bajtach. W przypadku bitmapy nie
skompresowanej rowne 0.
bixpelspermeter, biypelspermeter - ilosc pikseli na metr
biclrused - ilosc kolorow istniejacej palety, a uzywanych wlasnie
przez bitmape
biclrimporant - okresla ktory kolor bitmapy jest najwazniejszy, gdy
rowny 0 to wszystkie sa tak samo istotne.
--------------------------------------------
Ale spokojnie - nie musicie znac ich wszystkich, bo my nie bedziemy
wszystkich uzywac. Scisle mowiac, nie bedziemy uzywac ani jednego z tych pol!
No to po co to wszystko?
Po to, aby znac dlugosc naglowka pliku (54 bajty), ktory ominiemy przy
analizie pliku.
Po naglowku idzie paleta 256 kolorow * 4 bajty/kolor = kolejny 1kB. Jesli
macie jakies watpliwosci co do tego 1 kilobajta, to slusznie. Oczywiscie,
do opisu koloru wystarcza 3 bajty (odpowiadajace kolorom czerwonemu,
zielonemu i niebieskiemu - RGB), co daje razem 768 bajtow. Co czwarty bajt
nie zawiera zadnej istotnej informacji i bedziemy go pomijac (zmienna "z").
Zaraz po palecie idzie obraz, piksel po pikselu. Niestety, nie jest to tak
"logiczne" ustawienie, jak bysmy sobie tego zyczyli. Otoz, pierwsze 320
bajtow to ostatni wiersz obrazka, drugie 320 - przedostatni, itd. Dlatego
trzeba bedzie troszke pokombinowac.
Zanim jeszcze zaczniemy, nalezy sie przyjrzec, ktorych portow (choc to samo
mozna uzyskac wywolujac odpowiednie przerwanie) i dlaczego bedziemy uzywac
(patrzymy do pliku "ports.lst" w Spisie Przerwan Ralfa Brown'a):
===============================
03C8 RW (VGA,MCGA) PEL address register (write mode)
Sets DAC in write mode and assign start of color register
index (0..255) for following write accesses to 3C9h.
Don't read from 3C9h while in write mode. Next access to
03C8h will stop pending mode immediatly.
03C9 RW (VGA,MCGA) PEL data register
Three consequtive reads (in read mode) or writes (in write
mode) in the order: red, green, blue. The internal DAC index
is incremented each 3rd access.
bit7-6: HiColor VGA DACs only: color-value bit7-6
bit5-0: color-value bit5-0
===============================
Czyli, najpierw na 3C8h idzie numer rejestru dla danego koloru (rejestrow
jest 256 i kolorow tez), a potem na 3C9h ida trzy wartosci kolorow:
czerwonego, zielonego i niebieskiego, ktorych polaczenie daje nam
zadany kolor.
Ale dobierzmy sie wreszcie do kodu:
===============================
; Program wyswietla na ekranie kolorowy rysunek o rozmiarze
; 320x200 w 256 kolorach, umieszczony w pliku.
;
; nasm -O999 -o bmp1.com -f bin bmp1.asm
;
; Autor: Bogdan D., bogdandr (at) op (kropka) pl
;
; na podstawie kodu podpisanego "Piotr Sokolowski", napisanego w jezyku Pascal
org 100h
; =================================================================
start:
mov ax, 13h
int 10h ; uruchamiamy tryb graficzny 13h
; - 320x200x256
mov ax, 3d00h ; otwieramy plik tylko do odczytu
mov dx, nazwa_pliku
int 21h
jnc otw_ok
mov ah, 9
mov dx, blad_plik ; wyswietlane, gdy wystapil blad
int 21h
err:
mov ax, 4c01h ; wyjscie z kodem bledu=1
int 21h
otw_ok:
mov bx, ax ; bx = uchwyt do pliku
mov ah, 3fh ; czytanie z pliku
mov cx, 54 ; wyrzucamy 54 bajty naglowka
mov dx, smieci
int 21h
jc err
; =================================================
; wczytywanie palety z pliku:
; =================================================
xor si, si ; wskaznik do tablicy "paleta"
czytaj_pal:
mov ah, 3fh ; czytanie z pliku
mov cx, 4 ; czytam po 4 bajty - do b,g,r i "z".
; "z" odrzucamy
mov dx, b
int 21h
jc err
; ustawiamy palete:
mov al, [r]
shr al, 2
mov [paleta+si], al ; paleta[si] = [r] / 4
mov al, [g]
shr al, 2
mov [paleta+si+1], al ; paleta[si] = [g] / 4
mov al, [b]
shr al, 2
mov [paleta+si+2], al ; paleta[si] = [b] / 4
add si, 3 ; przejdz o 3 miejsca dalej - na
; kolejne wartosci RGB
cmp si, 256*3 ; sprawdz, czy nie zapisalismy juz
; wszystkich kolorow
jb czytaj_pal
; =================================================
; wysylanie palety do karty graficznej:
; =================================================
xor ax, ax
xor si, si ; SI = wskaznik do palety
mov dx, 3c8h ; port karty graficznej
wyslij_palete:
out dx, al ; wysylamy numer rejestru, wszystkie
; od 0 do 255
inc dx ; DX = port 3C9h
push ax
; zapisujemy kolorki: czerowny,
; zielony, niebieski.
mov al, [paleta+si] ; AL = czerwony (patrz petla
; "czytaj_pal")
out dx, al
mov al, [paleta+si+1] ; AL = zielony
out dx, al
mov al, [paleta+si+2] ; AL = niebieski
out dx, al
pop ax
add si, 3 ; przejdz do nastepnych wartosci
; kolorow
dec dx ; DX z powrotem 3C8h
inc ax ; wybierzemy kolejny rejestr koloru
; w karcie graficznej
cmp ax, 256 ; sprawdz, czy juz koniec pracy
jb wyslij_palete
; =================================================
; wczytywanie obrazka:
; =================================================
mov ax, 0a000h
mov ds, ax ; czytaj bezposrednio do
; pamieci ekranu
mov dx, 64000-320 ; DX = adres ostatniego wiersza
mov cx, 320 ; z pliku czytamy po 1 bajcie
obrazek:
mov ah, 3fh
int 21h ; czytaj 320 pikseli prosto na ekran
jc err
sub dx, 320 ; przejdz do wczesniejszego wiersza
jnc obrazek ; dopoki nie musimy "pozyczac" do
; odejmowania.
; pozyczymy dopiero wtedy, gdy
; DX < 320 - a to sie
; zdarzy dopiero, gdy DX = 0, czyli
; przerobilismy
; caly obrazek i ekran
; =================================================
; koniec programu:
; =================================================
mov ah, 3eh
int 21h ; zamknij plik
jc err
xor ah, ah
int 16h ; czekamy na klawisz
mov ax, 3
int 10h ; powrot do trybu tekstowego
mov ax, 4c00h
int 21h
; =================================================
; dane:
; =================================================
nazwa_pliku db 'rys1.bmp',0
blad_plik db 'Blad operacji na pliku!$'
smieci times 54 db 0
paleta times 768 db 0
b db 0
g db 0
r db 0
z db 0
kolor db 0
===============================
Mam nadzieje, ze kod jest dosc jasny. Nawet jesli znacie assemblera tylko w
takim stopniu, w jakim to jest mozliwe po przeczytaniu mojego kursu,
zrozumienie tego programu nie powinno sprawic Wam wiecej klopotow niz mnie
sprawilo przetlumaczenie go z Pascala.
Wyszukiwarka
Podobne podstrony:
DOS DIOD TUTDOS PWR TUTBMP TUTDOS MYSZ TUTDOS GRAF TUTDOS SPKR TUTDOS CPU TUTDOS BOOT TUTDOS SYS TUTBMP TUTDOS BIBL TUTBMP TUTDOS TSR TUTFUNFACE DOS OPISART121 tut 2compilar doswięcej podobnych podstron