Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Gint - fondu au gris (ou retour à la couleur) d'une image bopti
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Gint - fondu au gris (ou retour à la couleur) d'une image bopti

Posté le 10/01/2022 10:32

Hello,
j'aimerai avoir un effet de "rotation" de palette sur une image bopti p4 ou p4 (avec alpha) afin de faire un fondu au gris (image couleur --> image en niveau de gris) et/ou l'inverse (image en gris --> retour en couleur).

Pour ce faire j'aurais besoin de "choper" la palette originale de l'image bopti en RGB pour pouvoir la modifier et la réinjecter dans l'image avant un dimage()/dupdate().

C'est faisable ? Un indice pour acceder au membre palette d'une bopti ?

A plus et merci d'avance

Ciao

Sly


Dark storm Hors ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 10/01/2022 10:36 | #


Lephe va sûrement faire un pavé, mais le format bopti est documenté ici : https://gitea.planet-casio.com/Lephenixnoir/gint/src/branch/master/include/gint/display-cg.h#L80
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Citer : Posté le 10/01/2022 10:39 | #


Merci Dark Storm,
En effet
J'ai appuyé sur entrée et en relisant ma question, je me suis dit : "t'es C.N, regarde dans la structure de bopti_image_t".
Je vais essayer de jeter un oeil donc.
Merci bcp.
Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24261 Défis: 170 Message

Citer : Posté le 10/01/2022 10:48 | #


Techniquement ça fait pas partie de l'API, mais comme les formats risquent pas vraiment de changer, tu peux le faire oui.

Le format est décrit ici. Comme tu peux le voir, si tu as une image p4 standard, il "suffit" de regarder les 32 premières entrées de data[] pour avoir la palette.

La difficulté, c'est que tu ne peux pas modifier la variable puisqu'elle est constante (issue de la conversion de fxconv). Si tu veux t'en sortir, il faudra donc dupliquer l'image, ce qui nécessite de connaître la taille totale des données.

Cette fonction (de tête) devrait te dupliquer une image :

bopti_image_t *duplicate_image(bopti_image_t const *img)
{
    size_t size = sizeof(*img);
    if(img->profile == 0 || img->profile == 1) // PX_RGB565, PX_RGB565A
        size += img->width * img->height * 2;
    else if(img->profile == 2) // PX_P8
        size += img->width * img->height;
    else if(img->profile == 3) // PX_P4
        size += ((img->width + 1) / 2) * img->height;
    else return NULL;

    bopti_image_t *newimg = malloc(size);
    if(!newimg) return NULL;

    memcpy(newimg, img, size);
    return newimg;
}

Et ensuite tu peux modifier soit les pixels soit la palette.

Comme tu peux le voir ça manque un peu de partie publique (les noms des profils sont privés par exemple), je me note d'améliorer ça.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Citer : Posté le 10/01/2022 11:33 | #


OK Merci Lephé, effectivement ca aurait coincé si fxconv génère des data sous forme de constantes.

Du coup, il faudra aussi que je pense bien à faire une libération de mémoire à la fin pour pas avoir une fuite (chose qu'on fait pas du coup avec une image issue de fxconv.

Pour info, à toute fin utile, si cela peut intéresser quelqu'un d'autre, le niveau de gris correspondant à une couleur (R,G,B) est obtenu en calculant la moyenne M=(R+G+B)/3 et en appliquant cette couleur moyenne sur chaque composante (RGB)-->(M,M,M). Il s'agit ensuite de faire le morphing entre la couleur initiale et la couleur finale avant chaque appel à dimage()/dupdate() sur un nombre N d'itérations pour avoir le véritable effet de fondu.

A plus et merci

Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24261 Défis: 170 Message

Citer : Posté le 10/01/2022 11:35 | #


Excellent ! Tu ne peux pas échapper à l'allocation RAM, mais tu peux toujours te donner une unique copie pour tout le programme et la modifier à chaque fois que tu en as besoin. Maintenant que j'y pense, tu peux faire mieux : fxconv supporte un attribut section qui te permet de mettre l'image dans la RAM :

myimage.png:
    type: bopti-image
    section: .data

Auquel cas la variable est en lecture-écriture. J'ai en tête un cas peut-être où ça pourrait ne pas marcher (alignment), si tu essaies et que ça crashe signale-le moi et je corrigerai le truc immédiatement.

Edit : pour la luminosité, le facteur 1/3 partout c'est pas hyper hyper fidèle, y'a d'autres pondérations qui reflètent un peu mieux la perception de l'oeil humain.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Citer : Posté le 10/01/2022 11:45 | #


Ok, je vais essayer avec la section .data.

Pour le niveau de gris, c'est la version simple en effet.

il y a aussi la méthode de la luminance/chrominance, mais ce sera certainement pus lourd en calculs, donc si le rendu avec la moyenne passe, ce sera bien. Par contre si j'ai un résultat vraiment "dégueulasse", j'essaierai de l'implémenter.

Comme d'hab', il faut aviser en fonction

@+

Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24261 Défis: 170 Message

Citer : Posté le 10/01/2022 13:12 | #


En effet. Le risque c'est que si tu fais un fondu progressif, ie. tu pars de la couleur originale pour aller vers la moyenne (pondérée ou pas) tu as plutôt envie de préserver la luminosité durant toute la transition. Sinon, ton image risque de s'assombrir/éclaircir visuellement au passage.

Je le mentionne parce que les coefficients habituels sont assez loin du 1/3, par exemple le standard CCIR 601 (genre YCbCr) la formule est plutôt 0.299 R + 0.587 G + 0.114 B. Après y'a aussi le gamma qui s'en mêle.

Note (si jamais le 1/3 ne passe pas bien) que toutes ces multiplications sont aussi rapides à faire que 1/3, surtout que tes nombres sont tous petits (0..31 pour R/B et 0..63 pour B), tu as une myriade d'options, de multiplier puis faire un décalage de bits, à utiliser une table. Tu devrais vraiment pas avoir de problèmes de perfs à première vue (après si tu fais ça sur des très grandes surfaces genre tout l'écran ça se complique).
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Citer : Posté le 10/01/2022 13:27 | #


En fait je pense que je vais faire un pré-calcul de la palette, stocker les itérations pour ensuite juste faire un "dump" de la palette à utiliser dans l'image juste avant de l'afficher. Comme ça pas de problème de vitesse et ca devrait pas utiliser trop trop de mémoire (du moins ca devrait rester raisonnable). Je me cantonnerai donc aux formats P4 et P8 le RGBA565 serait je pense trop lourd en calcul.

Je te dirai quand je me serai mis dessus (peut-être ce soir ou demain), car là je passe le "polish" sur les niveaux de ML, la v1.0A est imminente. (j'avoue que j'avais sous estimé le temps de Beta test et d'écriture des niveaux )

Sly
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24261 Défis: 170 Message

Citer : Posté le 10/01/2022 13:29 | #


Bonne idée ! Avec ce niveau d'attention au détail ça promet d'être beau
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Citer : Posté le 10/01/2022 15:18 | #


Bon, j'ai tenté ça:

mon image arrive dans la variable village via un "extern bopti_image_t village;"
Je précise que l'image est codé en p8 via fxconv.

Je trifouille la palette (version goret pour le moment, on fera plus complexe après si j'arrive à faire fonctionner ):



    memcpy( palette, village.data, 512 ); // je sauvegarde la palette pour y revenir si besoin
    uint16_t paletteNB[256];

    for( unsigned char k=0; k<=255; k++)
    {
        unsigned char B = (unsigned char) (palette[k] & 0b0000000000011111);
        unsigned char G = (unsigned char) ((palette[k] & 0b0000011111100000) >> 5);
        unsigned char R = (unsigned char) ((palette[k] & 0b1111100000000000) >> 11);
        unsigned char Moy = (R+G+B)/3;
        paletteNB[k] = (uint16_t) (((Moy>>3) << 11) | ((Moy>>2) << 5 ) | (Moy>>3));
    }

    memcpy( village.data, paletteNB, 512 );



Et là l'émulateur freeze. J'ai pas tenté sur la machine physique, je voudrais pas la briquer
Je sais pas si c'est mon code qui est pourri ou si je tombe dans le cas que tu craignais Lephé.
Une idée ?
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Kikoodx Hors ligne Ancien labélisateur Points: 3011 Défis: 11 Message

Citer : Posté le 10/01/2022 15:28 | #


Il faut copier l'image avant de modifier la palette, sinon les données sont constantes (pour faire simple). Ce commit d'un de nos projets abandonnés fait juste ça (pour 90+E, mais le format a l'air assez similaire).

Edit : t'es sous 90+E en fait my bad
ouais ouais
Lephenixnoir Hors ligne Administrateur Points: 24261 Défis: 170 Message

Citer : Posté le 10/01/2022 15:34 | #


     for( unsigned char k=0; k<=255; k++)

Rappelle-moi le range d'un unsigned char ? :P

Aussi note que ça ne sert à rien de prendre des types autre que int pour toutes tes variables temporaires, ça te fait payer des extensions (calculs) en plus et tu ne gagnes pas un seul octet de mémoire.

Enfin je crois que ton G va de 0 à 63 plutôt que de 0 à 31 comme R et B donc le calcul n'est probablement pas la moyenne que tu imagines

(Je suis en train de penser que du coup tu peux faire (R + G + B) / 4, ce qui va plus vite, et qui donne plus de poids au vert comme dans les formules discutées précédemment)
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Citer : Posté le 10/01/2022 15:47 | #


Lephenixnoir a écrit :
     for( unsigned char k=0; k<=255; k++)

Rappelle-moi le range d'un unsigned char ? :P


Bon c'est officiel je suis un *$#&*ù£ !!!
Merci, du coup ça marche ....

Mais c'est juste immonde et hyper sombre, on va donc faire la version évoluée

Aussi note que ça ne sert à rien de prendre des types autre que int pour toutes tes variables temporaires, ça te fait payer des extensions (calculs) en plus et tu ne gagnes pas un seul octet de mémoire.


Ca je savais pas, merci pour l'info. Je vais optimiser un peu alors.

Enfin je crois que ton G va de 0 à 63 plutôt que de 0 à 31 comme R et B donc le calcul n'est probablement pas la moyenne que tu imagines
(Je suis en train de penser que du coup tu peux faire (R + G + B) / 4, ce qui va plus vite, et qui donne plus de poids au vert comme dans les formules discutées précédemment)


oui je gère tout en RGB565. Je vais essayer avec la luminance "officielle" et avec la division par 4 pour voir ce qui est le mieux.
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24261 Défis: 170 Message

Citer : Posté le 12/01/2022 00:28 | #


En jouant avec... une correction importante sur ma fonction de plus tôt :

bopti_image_t *duplicate_image(bopti_image_t const *img)
{
    size_t size = sizeof(*img);
    if(img->profile == 0 || img->profile == 1) // PX_RGB565, PX_RGB565A
        size += img->width * img->height * 2;
    else if(img->profile == 2) // PX_P8
        size += 512 + img->width * img->height;
//              ^^^^^
    else if(img->profile == 3) // PX_P4
        size += 32 + ((img->width + 1) / 2) * img->height;
//              ^^^^
    else return NULL;

    bopti_image_t *newimg = malloc(size);
    if(!newimg) return NULL;

    memcpy(newimg, img, size);
    return newimg;
}

J'avais oublié de compter les palettes dans la taille totale.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Slyvtt Hors ligne Maître du Puzzle Points: 2313 Défis: 17 Message

Citer : Posté le 12/01/2022 08:03 | #


Ah oui effectivement ;-)
Ca arrive même aux meilleurs ...
There are only 10 types of people in the world: Those who understand binary, and those who don't ...
Lephenixnoir Hors ligne Administrateur Points: 24261 Défis: 170 Message

Citer : Posté le 12/01/2022 08:07 | #


Surtout quand on écrit de tête ! Aïe aïe aïe...
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 31 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd