[THOMSON MO5] Afficher des photos

Cette catégorie traite de développements récents destinés à nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Répondre
Oursique
Messages : 11
Inscription : 04 août 2016 22:07

[THOMSON MO5] Afficher des photos

Message par Oursique »

[EDIT]Oups ! ça irait plus dans « Softwares et documentations / Développements actuels », si un admin passe par là, il ne semble pas que je puisse le faire moi-même. [edit fabien -> fait ]

Salut,

Je vous propose à mon tour un bricolage mais logiciel pour rester dans mon domaine.

Après avoir fait un petit logiciel de dessin pour me remettre dans le bain et jouer avec le crayon optique, j'ai voulu afficher une photo.

Bon déjà, les limitations sont nombreuses : une seule couleur par ligne de 8 pixels, limitation mémoire des listings BASIC et des données en RAM. Mais si on tient compte de toutes ces limitations, on peut générer un listing qui contient les données de la photo au format 40*200 (qui sera « étiré » en 320*200) et la routine d'affichage.

C'est ce que j'ai fait en Python, le langage que j'utilise aujourd'hui que j'en ai fait mon métier. Vous pardonnez la qualité du code pour un bricolage vite fait pour épater les enfants à qui je fais découvrir cette machine.

Code : Tout sélectionner

import sys


END = "\r\n"


def h2line(filename, output):
    output.write("1 CLS:SCREEN7,0,0")
    output.write(END)

    with open(filename) as fp:
        for lineno, line in enumerate(fp.readlines(), 2):
            output.write(str(lineno))
            output.write(" DATA ")
            output.write(line.strip().rstrip(','))
            output.write(END)

    for lineno, line in enumerate((
            " FOR Y=0 TO 191",
            " FOR X=0 TO 319 STEP 8",
            " READ C",
            " LINE(X,Y)-(X+8,Y),C",
            " NEXT X",
            " NEXT Y",
            " LINE INPUT A$",
            ), lineno):
        output.write(str(lineno))
        output.write(line)
        output.write(END)


if __name__ == '__main__':
    h2line(sys.argv[1], sys.stdout)
À noter : j'ai dû arrêter l'affichage à la dernière ligne non incluse, l'interpréteur se plaignait de ne pas trouver assez de données dans DATA. Et j'ai mis un « LINE INPUT A$ » pour éviter l'affichage du OK à la fin qui fait scroller l'affichage.

Pour générer le fichier source, j'ouvre la photo dans Gimp, je la réduis en 320x200 pour garder les proportions, puis 40x200 puis je la passe en mode indexé avec la palette de couleurs du MO5. L'astuce est d'exporter la photo au format « En-tête C (.h) » qui me génère déjà toute la liste des codes couleur. Je n'ai qu'à effacer ce qui ne m'intéresse pas dans le fichier.

Le listing en sortie ressemble à ceci (j'ai élidé pour la lisibilité) :

Code : Tout sélectionner

1 CLS:SCREEN7,0,0
2 DATA 0,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12
3 DATA 0,12,0,12,0,12,0,12,0,12,0,12,0,12,0,12
4 DATA 0,12,0,12,0,12,0,12
[...]
601 DATA 0,0,0,0,0,0,0,0
601 FOR Y=0 TO 191
602 FOR X=0 TO 319 STEP 8
603 READ C
604 LINE(X,Y)-(X+8,Y),C
605 NEXT X
606 NEXT Y
607 LINE INPUT A$
Voici le résultat, ici dans l'émulateur pour faciliter la capture d'écran mais le listing fonctionne bien sûr sur ma machine : [img https://pbs.twimg.com/media/CpKbqDTXYAA5yXj.png]https://pbs.twimg.com/media/CpKbqDTXYAA5yXj.png[/img]

Il est possible de rendre le listing plus compact en codant deux « pixels » dans un seul nombre, vu que chaque couleur occupe au maximum 4 bits. Peut-être même quatre mais j'avais eu des erreurs en testant.

Pour une future version, je pense stocker une version compressée de l'image, peut-être même un format plus courant comme BMP ou PNG et écrire la routine de décodage du format.
Pièces jointes
CpKbqDTXYAA5yXj.png
CpKbqDTXYAA5yXj.png (32.86 Kio) Consulté 4628 fois
Dernière modification par Oursique le 06 août 2016 13:33, modifié 1 fois.
__sam__
Messages : 7966
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [THOMSON MO5] Afficher des photos

Message par __sam__ »

Ca fait penser à http://www.pulsdemos.com/sinus01.html. A noter: comme tu as 2 couleurs par blocs de 8 pixels horiz, au lieu de réduire à 40x200, réduit à 80x200 et utilise les deux couleurs dans chacune des moitiés du bloc de 8 pixels horiz:

Code : Tout sélectionner

603 READ C1,C2
604 LINE(X,Y)-(X+3,Y),C1:LINE(X+3,Y)-(X+7,Y),-C2-1
Ca sera encore plus joli. Tu peux aussi faire un DEFINT A-Z au tout début du programme ce qui va l'accélérer.

Pour réduire l'occupation mémoire, je te conseille de stocker les data sous forme d'une chaine hexa:

Code : Tout sélectionner

DEFINT A-Z 'REM Acceration
DATA AABC012AF... ' REM: 80 codes hexa en ligne représentant les 80 couleurs d'une ligne
DATA 0001200BA00... ' REM: LIGNE SUIVANTE
...
FOR Y=0 TO 199
    READ LINE$
    FOR X=0 TO 39
       OCTET = VAL("&H"+MID$(LINE$,1+2*X,2))
       C1 = OCTET @ 16 ' REM: DIVISION ENTIERE sinon INT(OCTET/16)
       C2 = OCTET AND 15
       X8 = X*8
       LINE(X8,Y)-(X8+3,Y),C1
       LINE(X8+4,Y)-(X8+7,Y),-C2-1  ' REM:  OU NOT(C2)
    NEXT
NEXT
Plus d'infos sur la conversion d'images photo-réaliste sur: http://www.logicielsmoto.com/phpBB/view ... ?f=3&t=383
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Oursique
Messages : 11
Inscription : 04 août 2016 22:07

Re: [THOMSON MO5] Afficher des photos

Message par Oursique »

Ah, c'est ça cette histoire de couleurs négatives, je n'avais pas vu l'intérêt en lisant le guide du MO5, mais je vais pouvoir adapter mon programme.
__sam__
Messages : 7966
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [THOMSON MO5] Afficher des photos

Message par __sam__ »

Oui c'est ca les couleurs négatives: c'est les couleurs du "fond" qui ne se mélangent pas avec celles de la "forme" (positives).

Pour aller encore plus vite que de tracer des lignes, tu peux utiliser le color-clash à ton intéret.

Code : Tout sélectionner

DEFINT A-Z
' AFFICHAGE MOTIF FORME/FOND
FOR X=0 TO 319 STEP 8
   BOXF(X,0)-(X+3,199),-POINT(X,0)-1 ' TRUC: la couleur sera invisible en prenant la forme correspondant à la couleur de fond
NEXT
....
FOR X..
FOR Y..
   'LINE(X8,Y)-(X8°3,Y),C1.... retiré et rempacé par les deux instructions infiniment plus rapides qui suivent:
   PSET(X8,Y),C1 ' les 4 pixels horiz "forme" sont colorés d'un coup grace au color-clash
   PSET(X8+4,Y),-C2-1 ' les 4 autres pixels "fond" sont colorés en C2 d'un coup, toujours grace au color-clash
NEXT
NEXT
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Oursique
Messages : 11
Inscription : 04 août 2016 22:07

Re: [THOMSON MO5] Afficher des photos

Message par Oursique »

Merci pour ton aide, j'ai pu effectivement doubler la résolution horizontale.

La technique du color clash a l'air intéressante mais donne des résultats bizarres, il doit y avoir une coquille quelque part. Je relirai à tête reposée.

Par contre, l'optimisation DEFINT a l'air négligeable, en tout cas comparé aux délais de tracé graphique.
Pièces jointes
La même photo avec la résolution double.
La même photo avec la résolution double.
Capture du 2016-08-06 17-56-38.png (32.55 Kio) Consulté 4594 fois
Capture du 2016-08-06 15-41-21.png
Capture du 2016-08-06 15-41-21.png (56.64 Kio) Consulté 4610 fois
Dernière modification par Oursique le 06 août 2016 18:02, modifié 2 fois.
Oursique
Messages : 11
Inscription : 04 août 2016 22:07

Re: [THOMSON MO5] Afficher des photos

Message par Oursique »

OK en fait l'espèce de reset de tout l'écran n'est pas optionnel, il fait partie de l'astuce. Donc je n'ai pas encore compris pourquoi ça marche même si j'ai bien compris qu'on écrit deux fois chaque ligne de chaque caractère, une fois avec la couleur de forme, une fois avec la couleur de fond.

Mon programme à jour :

Code : Tout sélectionner

import sys


END = "\r\n"


def h2line(filename, output):
    output.write("1 CLS:SCREEN7,0,0:DEFINT A-Z")
    output.write(END)

    # Lit tous les pixels et encode au format hexadécimal
    pixels = []
    with open(filename) as fp:
        for line in fp.readlines():
            pixels += [hex(int(p))[2:].upper() for p in line.strip().rstrip(',').split(',')]
        
    # 80 pixels par ligne de DATA
    lineno = 2
    for y in range(0, len(pixels), 80):
        output.write(str(lineno))
        output.write(" DATA ")
        output.write("".join(pixels[y:y + 80]))
        output.write(END)
        lineno += 1

    for line in (
            " ' AFFICHAGE MOTIF FORME/FOND",
            " FOR X=0 TO 319 STEP 8",
            " BOXF(X,0)-(X+3,199),-POINT(X,0)-1",
            " NEXT X",
            " ' DEBUT AFFICHAGE",
            " FOR Y=0 TO 191",
            " READ L$",
            " FOR X=0 TO 39",
            ' O=VAL("&H"+MID$(L$,1+2*X,2))',
            " C=O@16",
            " F=O AND 15",
            " X8=X*8",
            " ' COLOR CLASH",
            " PSET(X8,Y),C",
            " PSET(X8+4,Y),-F-1",
            " NEXT X",
            " NEXT Y",
            " LINE INPUT A$",
            ):
        output.write(str(lineno))
        output.write(line)
        output.write(END)
        lineno += 1


if __name__ == '__main__':
    h2line(sys.argv[1], sys.stdout)

__sam__
Messages : 7966
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [THOMSON MO5] Afficher des photos

Message par __sam__ »

Une suggestion préliminaire qui pourrait amméliorer la qualité des images: les images des giraffes sont pas mal, mais il y a de grosses lignes verticales bien visibles avec du noir uniforme. On peut amméliorer ca je pense.

Idée :idea: : au lieu de faire la réduction de couleur avec diffusion d'erreur en 80x200, commence par faire une rotation de 90 à gauche pour avoir une image en 200x80. Effectue ensuite la réduction de couleur + diffusion erreur dans ce format (i.e. une image plus large que haute), et enfin rebascule l'image de 90° à droite pour revenir au 80x200. Je pense que cela fera apparaitre un effet "damier" sur les pixels dont les couleurs se mélangeront mieux du coup.
Oursique a écrit :OK en fait l'espèce de reset de tout l'écran n'est pas optionnel, il fait partie de l'astuce. Donc je n'ai pas encore compris pourquoi ça marche même si j'ai bien compris qu'on écrit deux fois chaque ligne de chaque caractère, une fois avec la couleur de forme, une fois avec la couleur de fond.
En fait c'est simple, mais plutot que d'expliquer avec des mots, je te propose d'experimenter pas à pas ce que fond:

Code : Tout sélectionner

pset(160,100),-1
pset(160,100),-2
Tu vois que la couleur noir puis rouge sont recopiés sur les 8 pixels hoizontaux dans lequel on a fait le "pset". C'est le color clash qui produit ca. Donc en affichant 1 pixel, on en colorie 8 d'un coup. C'est plus rapide.

Ensuite, ajoute un pixel blanc au milieu:

Code : Tout sélectionner

pset(164,100),7
et rejoue les 2 psets précédent chacun à son temps: tu vois que l'on change la couleur des 8-1=7 pixels de fond, mais que le pixel blanc reste là inchangé. Donc le pset negatif ne change que la couleur des pixels de fond.

Similairement, le pset d'un pixel de forme (couleur positive) va s'étendre lui aussi à tous les pixels de forme du même groupe de 8pixels. C'est toujour le color-clash qui fait cela. L'astuce est alors d'initialiser l'écran avec les boxf() pour faire que la 1ère moitié des blocs de 8 soient de couleur "forme", et l'autre moitié de couleur "fond". Ensuite quand on affiche une couleur forme dans la zone des pixels forme, elle les contamine tous. On a coloré 4 pixels avec un seul pset. Idem avec une un pset de couleur "fond" dans la zone des pixels "fond".

Voilà c'est tout simple. Mais mince, je me rend compte que j'ai donné une explication alors que je voulais avant tout te laisser experimenter avec le color-clash pour que tu te fasse l'intuition de comment l'utiliser pour afficher plus vite l'image.

Pour aller encore beaucoup, beaucoup plus vite, il faut directement poker en mémoire vidéo. Le plus rapide et le plus compact étant alors d'avoir un fichier "BIN" contenant le contenu (heuuu c'est moche cette expression) de la RAM couleur. L'afficheur basic sera alors tout vide. Il n'aura qu'à commuter l'écran pour que la zone &H000-&H3FFF pointe sur la zone "couleur", puis charge rapidement avec un "LOADM" les couleurs forme/fond à afficher pour chaque groupe de 8pixels. Enfin, je dis rapidement, mais avec la K7 tout est relatif. Pour aller encore,encore plus vite il faut compresser les données sur K7 et décompresser à la volée en ram vidéo. Mais ca devient bien plus complexe. (Nota: un bon compresseur existe et a été porté sur thomson: EXOMIZER 2).
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Oursique
Messages : 11
Inscription : 04 août 2016 22:07

Re: [THOMSON MO5] Afficher des photos

Message par Oursique »

Merci pour l'explication, ce que j'avais perdu de vue c'est qu'au démarrage, la zone mémoire écran n'est pas considérée comme remplie de cyan mais vide (transparent ?). C'est à partir du moment où l'on commence à remplir la mémoire qu'il va colorer tous les pixels déjà écrits dans la même ligne de 8. J'imagine qu'il a un flag ou quelque chose pour distinguer une zone vierge d'une zone remplie de noir.

Je voulais effectivement ensuite jouer avec PEEK et POKE et la zone écran. Je ne pense pas arriver à faire l'équivalent d'un double buffer mais peut-être accélérer un peu.

J'avais pensé aussi stocker l'image dans un format binaire et la faire charger avec LOADM mais je finirais par écrire deux programmes, un qui écrit l'image sur cassette et un autre qui ne fait que la lecture. Pourquoi pas, j'aurais une cassette avec une photothèque dedans et je choisirais l'image à afficher au chargement, ou même faire un diaporama.

Ce petit programme pour me remettre dans le bain commence à devenir ambitieux. :-D
__sam__
Messages : 7966
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [THOMSON MO5] Afficher des photos

Message par __sam__ »

Oursique a écrit :Merci pour l'explication, ce que j'avais perdu de vue c'est qu'au démarrage, la zone mémoire écran n'est pas considérée comme remplie de cyan mais vide (transparent ?). C'est à partir du moment où l'on commence à remplir la mémoire qu'il va colorer tous les pixels déjà écrits dans la même ligne de 8. J'imagine qu'il a un flag ou quelque chose pour distinguer une zone vierge d'une zone remplie de noir.
Un pixel a deux états: couleur forme ou couleur fond, et un groupe de 8 pixels a une couleur de forme et une couleur de fond. Au démarrage l'écran est vide: tous les groupes de 8 pixels sont en forme=bleu, fond=cyan et tous les pixels sont en couleur "fond". Résultat = cyan uniforme.

Dans mon init avec les boxf je donne la couleur -point(X,0)-1, ce qui revient à donner au groupe de 8 pixel la même valeur forme que celle du fond. Ainsi, ce qu'on écrit en pixel forme (les bandes verticales que tu appelles noir je suppose) seront donc de la même couleur que celle de fond. Elles seront invisibles.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
6502man
Messages : 12312
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: [THOMSON MO5] Afficher des photos

Message par 6502man »

Au cas ou BMP2MO5 :wink:
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Répondre