Afficher bitmap 256 couleurs

Résolu
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010 - 31 août 2004 à 23:26
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010 - 4 sept. 2004 à 12:53
salut,

voila j'aimerai afficher un bitmap de 256 a l'ecran en mode 320*200*256 ( fonction 12h de l'interruption 10h )

j'ai fais un prog qui d'abord ouvre le bitmap ( int 21h ah=3dh )
ensuite je place le curseur a l'octet 54 ( int 21h ah=42h ), puis je lis 10 000 octets car je sais que l'image fait 100*100 ( int 21h ah=3Fh ) et je place tt sa ds un buffer .
puis ensuite je fais sa pr afficher directement sur l'ecran :
; Initialisation du segment pour l'adresse de  l'ecran
mov ax, 0A000h
mov es, ax

mov bx, 0
xor di, di

mov cx, 10000
boucle:

mov al, buffer+di
;shl al, 2
inc bx
inc di
mov byte ptr es:[bx], al

push bx

mov ax, di
xor dx, dx
mov bx, 100
div bx

pop bx

cmp dx, 0
jne non
add bx, 220
non:

loop boucle


mais ia un gros pb il m'affiche n'importe quoi sur l'ecran .
je sais pas trop ce que c'est je pensais qu'il fallait peut etre convertir la couleur prise ds le bitmap mais je ne suis pas sur
et si c'etait le cas comment faire ?

merci d'avance
@+

36 réponses

Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
2 sept. 2004 à 19:51
1.Principe
Toutes les fonctions VESA sont appelées par l'intermédiaire de l'interruption 10h, fonction 4Fh. Toutes les fonctions VESA sont donc en fait des sous-fonctions de la fonction 4Fh. Pour l'instant, seules les sous-fonctions 00h à 08h sont utilisées. Les sous-fonctions 09h à 0FFh sont réservées pour des ajouts ultérieurs.
Chaque appel à une sous-fonction renvoie le status dans le registre AX :
AL = 4Fh : Fonction supportée
Ou AL <> 4Fh : Fonction non supportée
AH = 00h : Appel de la fonction réussi
Ou AH <> 00h : Appel de la fonction non réussi

2.Fonction 00h : Lire les spécificités de la carte Super VGA
Cette fonction permet de prendre connaissance des techniques offertes par la carte Super VGA installée et déterminer si les fonctions VESA sont soutenues.
Entrée :
AH = 4Fh
AL = 00h
ES:DI : Pointeur FAR sur le buffer Info

Sortie :
AX = status (voir 1)
Tous les autres registres sont conservés

Remarques :
Le buffer Info dont l'adresse est à transmettre à la fonction doit disposer de 256 octets. Si la fonction s'exécute correctement, vous obtenez les informations suivantes :

Structure du buffer Info :

Offset Type Contenu
00h db 'VESA' Signature VESA
03h db ? Version VESA, Numéro de version principal
04h db ? Version VESA, Numéro de version secondaire
05h dd ? Pointeur FAR sur chaîne ASCII contenant le nom du fabricant
09h db 4 dup(?) Performances de l'environnement vidéo
0Dh dd ? Pointeur FAR sur liste contenant les numéros des modes vidéo reconnus
11h dw ? Nombre de chunks de 64Ko
13h db 236 dup(?) Réservé

- Le nom du fabricant se termine par un caractère ASCII 0
- La liste des numéros de codes des modes vidéo reconnus, transmise dans le dernier champ du buffer, se compose de divers Words indiquant chacun le code d'un mode (voir III/2. ). Cette liste se termine par un Word de valeur 0FFFFh. Sa longueur varie d'une carte à l'autre.

- Structure du dword des performances :
Bit 0 = 1 : largeur de la palette DAC modifiable
Bit 0 = 0 : largeur de la palette DAC fixée à 6 bits par couleur primaire
Bits 1 à 31 : Réservés

10.Fonction 08h : Contrôle de la palette DAC
Certaines palettes DAC sont configurables pour fournir des définitions de couleurs en 6 bits, 8 bits, ou plus, par composantes primaires (RGB). Notez que la palette est remise à zéro (palette VGA 6 bits) lors d'une initialisation du mode VESA par la fonction 02h

a.Sous-fonction 00h : Définir la largeur de la palette
Entrée :
AH = 4Fh
AL = 08h
BL = 00h
BH = Nombre de bits par couleur désirés
Sortie :
AX = status (voir 1)
BH = Nombre de bits par couleur effectifs
3
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
1 sept. 2004 à 03:41
essaye plutôt le mode 13h.
d'autre part en format 256 couleurs, on n'a pas directement la couleur, mais un numéro de couleur, il faut donc aller chercher la couleur dans la palette de couleur.
voir le format d'un fichier BMP.

Daniel
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
1 sept. 2004 à 11:17
oui je me suis tromper , je voulais dire 13 . j'ai deja essayer avec le mode 12 , mais c'est encore pire , il m'affiche que du noir et du blanc .
tu peux expliquer + en detail comment je peux faire pr recuperer la couleur ?
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
1 sept. 2004 à 14:37
re ,

j'ai chercher et j'ai trouver des informations sur la palette .
mais j'ai un autre probleme comment je convertis la couleur rvb que j'ai trouvé ds la pallete pr pouvoir l'afficher sur l'ecran . j'ai crus comprendre qu'il y avais une palette vga mais je ne sais pas comment on y accede
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
1 sept. 2004 à 16:56
Salut,
Bien que je préfère de beaucoup masm32 j'ai un peu tater du bitmap en assembleur du temps ou c'était faisable.
Le format Bitmap est le plus simple a lire,rien n'est compressé.
Il faut se munir du format de fichier,il y a un site pour ça.
Ensuite il faut trouver l'emplacement ou se trouve défini le nombre de lignes,la longueur de lignes et l'entrelacement.
Une fois muni de ces données il faut avoir l'adresse de fin d'entête du fichier et de début des données graphiques.
Sa y est ,c'est gagné:envoyé le nombre d'octets correspondant a la longeur de lignes a l'écran,changer de lignes et ainsi de suite.
La connaisance de départ est le format de fichier
Savoir si les cartes graphiques supportent maintenant l'adressage directe par es ce qui n'est pas évident.De meilleurs résultats sont envisageables avec une int (probablement int 10h).
Vérifier que le système ne bloque pas ce type d'écriture un peu sauvage.
ToutEnMasm
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
1 sept. 2004 à 20:32
Salut,
comme tu as pu voir, on trouve dans le fichier BMP après une entête de 54 octets, la palette de couleur a une taiile de 1024 octets soit 4 octets par couleur.
ces 4 octets correspondent à un octet pour le Bleu, un octet pour le Vert, un octet pour le rouge, et un octet inutilisé.
récapitulation:
BITMAPFILEHEADER....14 octets
BITMAPINFOHEADER ...40 octets
RGBQUAD.....................4 octets par couleur
BYTE.............................l'image Bitmap
dans l'image Bitmap, un octet correspond à 1 pixel, la couleur se trouvant dans la table de couleur.
pour l'écran en mode 256 couleurs, chaque point de l'écran de la RAM vidéo est représenté par un octet qui correspond à une couleur entre 0 et 255 pour ce point. La carte VGA considère ce code couleur comme un index direct de la table de couleurs DAC d'où est extraite la couleur finale du poin concerné.
ouf! j'espère avoir été clair.
conclusion il faut changer les couleurs des registres DAC.
Pour modifier un registre de couleur DAC, il faut mettre son numéro (0-255) dans le registre Pel Write Address (3C8h), et il fait transmettre la nouvelle couleur dans le registre Pel Data (3C9h) ceci se faisant en trois fois:
dans le style:

'DS:SI pointe sur la table de couleur (celle du BMP)
MOV CX,256
XOR BX,BX
MOV DX,3C8h
debut:
'BX contient le numéro de couleur
MOV AL, BL
OUT DX,AL
INC DX
LODSB
'envoyer le Bleu
OUT DX,AL
LODSB
'envoyer le Vert
OUT DX,AL
LODSB
'envoyer le Rouge
OUT DX,AL
DEC DX
INC BX
LOOP debut

en principe on est pas obligé de répéter le OUT dans le registre 3C8h, l'incrément se faisant automatiquement aprés la sortie des 3 composants de couleur dans le registre Pel Data... (à tester)

Bonne Prog.
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
1 sept. 2004 à 22:33
tt dabord merci de vos reponse .

Gobillot > j'ai regarder ton code , merci , j'ai po tt compris mais je regarderai + en detail demain et je vs dirais si sa marche .
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
1 sept. 2004 à 23:06
de rien mat74.
tester la fin de ligne à chaque octet avec une div c'est pas très performant.
soit DS:SI début de la Bitmap et ES:DI début de l'adresse vidéo

;dimensions à prendre dans l'entête 
MOV CX,100   ;Largeur de l'image
MOV AX,100   ;Hauteur de l'image

MOV BX,320
SUB BX,CX
boucle:
PUSH CX
REP MOVSB
POP CX
ADD DI,BX
DEC AX
JNZ boucle
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
2 sept. 2004 à 13:24
voila j'ai presque reussi a aficher l'image mais il reste qqs petit pb.
au niveau de la palette c'est bon car j'ai les bonne couleur a l'ecran .
mais le dessin est un peu mélanger .
au depart le dessin etait inversé hrizontalement et verticalement.

donc j'ai fais sa et maintenant cest + inversé mais c'est encore decalé.

Changer_pos_curseur_fichier handle,01h,1078

Lire_fichier handle,buffer,10000,0

mov bx, 100*320
xor di, di
mov dx, 100
mov cx, 10000
boucle:

mov al, buffer+di
mov byte ptr es:[bx], al
inc bx
inc di
dec dx

cmp dx, 0
jne non
sub bx, 420
mov dx, 100
non:

loop boucle


l'image :
1 2 3
4 5 6
7 8 9

et l'image a l'ecran
3 1 2
6 4 5
9 7 8

la derniere colone est passé en 1er

en + le bas de l'image est coupé et au dessus de l'image il y a qq ligne de n'importe koa

comment faire ?
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
2 sept. 2004 à 14:25
Oui surprise, dans un fichier BMP les lignes sont inversées, on trouve la dernière ligne au début et la première ligne à la fin.
Par contre au niveau d'une ligne, les octets vont bien de gauche à droite.
C'est quoi les dimensions de l'image ? 100x100 320x100 ?
On les trouve en position 12h et 16h en Dword.
je te fait le plan pour un 320x100

entête position 0 Longeur 54
palette position 54 Longeur 1024
dernière ligne position 1078 Longueur 320
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
première Ligne position 32758 Longueur 320

total fichier = 54 + 1024 + 320*100 --> 33078

tu dois partir de la fin moins Longueur d'une ligne donc bx=32758 au départ et soustraire Longueur d'une ligne plus 320
donc sub bx,640

mais pourquoi tu met dx à 100 ?

pour du 100x100 bx=10978 sub bx,420 dx=100
pour du 100x320 bx=32978 sub bx,420 dx=100
pour du 320x200 bx=64758 sub bx,640 dx=320
pour du 320x100 bx=32758 sub bx,640 dx=320
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
2 sept. 2004 à 14:48
bon j'ai tout faux parce que pour moi bx c'était le fichier et di l'adresse vidéo.
je rectifie:
au départ bx=0 (vidéo) et di=10978 (fichier)
à chaque ligne bx=bx+220 et di=di-420
ou le contraire
au départ bx=32000 (vidéo) et di=1078 (fichier)
à chaque ligne bx=bx-420 et di=di+0

c'est ça t'as fait la deuxième méthode en partant du bas de l'écran. donc la seule différence que je vois c'est di=1078 au départ.
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
2 sept. 2004 à 15:27
sa y est j'ai trouver le pb , c'etait bidon .
en fait je sautais l'en tete , puis je lisais la palette et la je redecalais de 1078 octet ds le fichier alors que le curseur etait deja sur le debut de l'image et donc sans cette connecrie sa marche nickel .
merci a ts de m'avoir aidé parce que tt seul j'etait un peu ds la me*** pr trouver tt sa
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
2 sept. 2004 à 17:32
bon dsl mais j'ai encore un pb

voila j'ai essayer d'afficher un bmp tjs en 256 couleurs mais avec d'autres couleurs que les couleurs basiques comme le rouge et le bleu et la pb sa marche pas il me met du noir a la place
pk ?
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
2 sept. 2004 à 17:46
tu peux donner ton code.

Daniel
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
2 sept. 2004 à 18:02
voila le code

include lib_fich.inc
include lib_dos.inc

.386

code segment use16

assume cs:code, ds:data, ss:pile

debut:

mov ax, data
mov ds, ax

; Initialisation du segment pour l'adresse de l'ecran
mov ax, 0A000h
mov es, ax

; initialisation du mode graphique 13 = 320*200*256
mov ax, 13h
int 10h

; on ouvre le fichier bp
Ouvrir_fichier "des.bmp"
; si il y a une erreur
jc erreur
; on stocke le handle
mov handle, ax

; la largeur du bmp
Changer_pos_curseur_fichier handle,01h,18
Lire_fichier handle,buff,4,0
xor dx, dx
mov dh, buff+1
mov dl, buff
mov l_bmp, dx

; la hauteur du fichier
Lire_fichier handle,buff,4,0
xor dx, dx
mov dh, buff+1
mov dl, buff
mov h_bmp, dx

; nb total de pixel ds l'image = longueur*hauteur
mov ax, h_bmp
mul l_bmp
mov nb_pixel, ax

;Ecrire_nb l_bmp
;Ecrire_nb h_bmp
;Lire_caractere_sans_echo

; on defini la pos apres l'en tete du fichier
Changer_pos_curseur_fichier handle,01h,28
; on lit la palette
Lire_fichier handle,palette,1024,0

; le port d'indexe pel write
mov dx, 03C8h
xor al, al
out dx, al
; 256 tour
mov cx, 256
; la palette
mov di, offset palette
; pel data
mov dx, 03C9h
xor ah, ah

pal:

mov al, [di+2]
out dx, al

mov al, [di+1]
out dx, al

mov al, [di+0]
out dx, al

;mov al, [di]
;out dx, al

add di, 3

loop pal

; on lit l'image
mov di, nb_pixel
Lire_fichier handle,buffer,60000,0

; on commence en bas car l'image est inversé ds le bmp
; ax = hauteur_bmp*taille_ligne_ecran
mov ax, 320
mul h_bmp
mov bx, ax
; on met l'indice a 0
xor di, di
; cx = nb total de pixel ds l'image ( longueur*hauteur )
mov cx, nb_pixel
; dx = longueur_bmp
mov dx, l_bmp

boucle:

; on met ds al la couleur au debut du buffer
mov al, buffer+di
; puis on l'ecrit sur l'ecran
mov byte ptr es:[bx], al
; on augmente la pos a l'ecran
inc bx
; on augmente l'indexe du buffer
inc di
; on decrement la taille de l'image
dec dx

; pr determiner si c'est la fin d'une ligne
cmp dx, 0
jne non
; si c'est le cas on enleve longueur_bmp+longueur_ligne_ecran
; car on ecrit de gauche a droite et de bas en haut
mov si, 320
add si, l_bmp
sub bx, si
; puis on remet dx = longueur_bmp pr recommencer l'operation
mov dx, l_bmp
non:

loop boucle

; on attend l'appuis d'1 touche
; pr laisser le tps d'admirer cette belle image
Lire_caractere_sans_echo

; on a fini de lire le fichier on peut donc le fermer
Fermer_fichier handle

; remettre le mode normal
mov ah, 00h
mov al, 03h
int 10h

jmp fin

; en cas d'erreur
erreur:

Ecrire_chaine <"erreur">

fin:

mov ah, 4ch
int 21h

code ends

data segment use16

buffer db 60000 dup (?)
palette db 1024 dup (?)
handle dw ?
l_bmp dw ?
h_bmp dw ?
buff db 2 dup (?)
nb_pixel dw ?

data ends

pile segment stack

remplissage db 256 DUP (?)

pile ends

end debut
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
2 sept. 2004 à 18:11
j'ai essayer sa a la place de mon code pr la palette mais sa marche pas +

mov si, offset palette
;'DS:SI pointe sur la table de couleur (celle du BMP)
MOV CX,256
XOR BX,BX
MOV DX,3C8h
pal:
;'BX contient le numéro de couleur
MOV AL, BL
OUT DX,AL
INC DX
LODSB
;'envoyer le Bleu
OUT DX,AL
LODSB
;'envoyer le Vert
OUT DX,AL
LODSB
;'envoyer le Rouge
OUT DX,AL
DEC DX
INC BX
LOOP pal
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
2 sept. 2004 à 18:21
je vois 2 choses pour les couleurs.
dans ton code:
1 - faut ajouter 4 à di et non pas 3
2 - je suis pas sur de l'ordre

mov al, [di+0]
out dx, al
mov al, [di+1]
out dx, al
mov al, [di+2]
out dx, al
add di, 4

dans mon code il manque un inc si avant le Loop
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
2 sept. 2004 à 18:31
je viens d'essayer sa

mov al, [di+0]
out dx, al
mov al, [di+1]
out dx, al
mov al, [di+2]
out dx, al
add di, 4

mais sa ne change rien

pr info l'image que je dois afficher est composer de niveau de rouge et a l'ecran je vois du vert et du bleu .
je sais pas si c'est important mais bon
0
Gobillot Messages postés 3140 Date d'inscription vendredi 14 mai 2004 Statut Membre Dernière intervention 11 mars 2019 34
2 sept. 2004 à 18:35
Alors essaye d'inverser:
mov al, [di+2]
out dx, al
mov al, [di+1]
out dx, al
mov al, [di+0]
out dx, al
add di, 4
0
cs_mat74 Messages postés 241 Date d'inscription dimanche 10 août 2003 Statut Membre Dernière intervention 16 juin 2010
2 sept. 2004 à 18:41
ben qd j'essaie sa me donne une image verte avec un peu de vert .
y a du progret , y a un peu de rouge maintenant
0
Rejoignez-nous