:: PlayerAdvance.org ::  

Précédent   :: PlayerAdvance.org :: > :: Forums Hébergés :: > OldSchool Library > Aide au développement

Aide au développement Aide sur l'utilisation d'OSLib

Publicité

Réponse
 
Outils de la discussion Modes d'affichage
Vieux 12/09/2008, 19h11   #1
Akabane87
Membre
 
Date d'inscription: 01/07/2008
Messages: 14
Par défaut Ecrire un png avec canal alpha à partir d'un png source

Bonjour à tous, c'est encore et toujours le même problème qui me pousse à poster sur ce forum.
En fait, je cherche depuis fort longtemps un moyen avec des fonctions de l'oslib déjà existantes d'enregistrer un png avec un canal alpha. Le problème, c'est que je me retrouve toujours avec une image certes 24 bits, mais qui est entièrement transparente si je l'ouvre dans mon programme ou avec gimp et correcte mais sans transparence (fond noir) si je l'ouvre avec photofiltre studio.

Je suis donc arrivé à la conclusion que l'image est bien enregistrée, mais avec une alpha de 0 sur tous les pixels (la raison de l'exception avec photofiltre studio (qui gère parfaitement la transparence alpha) m'échappe encore).

Pour résumer la situation exacte, j'ai besoin d'un programme qui ouvre un png 24 bits (qui contient des dégradés de transparence) pour modifier totalement son contenu à partir de morceaux de l'original.
Pour cela, je créé une surface entièrement vide de 24bits, je swap cette surface avec le buffer, j'affiche tous mes morceaux sur l'écran (donc l'image), je reswap les buffer et je fais un oslWriteImageFilePNG() sur l'image et j'obtiens ce que j'ai décrit plus haut.


Voilà le code que j'ai écrit (à l'arrach, mais c'était pour tester ):

Code:
int main(int argc, char* argv[])
{	
	//Initialization
	oslInit(0);							//The lib
	oslInitGfx(OSL_PF_8888, 1);			//Gfx
	oslInitAudio();						//Sound

	//Quit directly if a file could not be found
	oslSetQuitOnLoadFailure(1);

	OSL_IMAGE *img = oslLoadImageFilePNG("screenshot.png", OSL_IN_RAM | OSL_SWIZZLED, OSL_PF_8888);
	img->x=200;
	
	OSL_IMAGE *drawBuf=NULL;
	
	while (!osl_quit)
	{
		//osl_skip indicates that frameskipping should be applied. Don't render anything when osl_skip is true!
		if (!osl_skip)		
		{
			oslStartDrawing();

			oslDrawFillRect(0,0,480,272,RGB(255,255,255));

			if(drawBuf!=NULL)
				oslDrawImage(drawBuf);


			if (osl_pad.pressed.triangle)
			{
				drawBuf = oslCreateImage(480, 272, OSL_IN_VRAM, OSL_PF_8888);
				oslSetDrawBuffer(drawBuf);
			}

			//oslSetImageTileSize(img, 0, 32, 96, 96);
			oslDrawImage(img);

			if (osl_pad.pressed.triangle)
			{
				//Restore the default drawbuffer
				oslSetDrawBuffer(OSL_DEFAULT_BUFFER);
				oslWriteImageFilePNG(drawBuf, "screenshot.png", OSL_WRI_ALPHA);
				//oslDeleteImage(drawBuf);
			}
			
			oslEndDrawing();
		}

		oslReadKeys();

	
		oslEndFrame();
		oslSyncFrame();
	}

	oslEndGfx();
	oslQuit();
	return 0;
}
Je suis presque quasiment sûr que c'est possible de le faire avec oslib sans pour autant créer sa propre fonction d'écriture png. Mais le problème, c'est que je ne suis même pas sûr que le problème vienne vraiment de cette fonction.
Akabane87 est déconnecté   Réponse avec citation

Publicité

Vieux 15/09/2008, 09h35   #2
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

à mon avis tu vas devoir dessiner dans ton image vide sans la swapper avec le buffer, en y allant un pixel après l'autre...
si tu passes par le buffer, tu vas perdre le canal alpha et je crois que tu ne peux rien y faire.
une fois que t'as fini de dessiner dans ton image tu pourras l'enregistrer avec oslWriteImageFilePNG sans problème.

edit: ceci pourrait également t'intéresser, j'y ai mis une fonction qui crée une copie du buffer et remet le canal alpha à 255.
__________________
Essayez mon dernier jeu sur iPhone:


Dernière modification par daaa57150 ; 15/09/2008 à 09h40.
daaa57150 est déconnecté   Réponse avec citation
Vieux 15/09/2008, 17h01   #3
Akabane87
Membre
 
Date d'inscription: 01/07/2008
Messages: 14
Par défaut

Merci beaucoup daaa57150, je n'avais pas testé cette version la dernière fois. Je l'essaie dès que j'ai le temps. J'espère juste que ça ne prend pas trop de temps à exécuter, parce-que je vais avoir besoin de m'en servir au démarrage de mon HB .
Akabane87 est déconnecté   Réponse avec citation
Vieux 15/09/2008, 18h00   #4
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

dans mon lien précédent je parlais de la fonction getBufferCopy. Ma fonction drawImageOnImage je l'ai encore modifiée après en fait, histoire d'intégrer les optimisations de nesgba.
c'est des fonctions un peu lentes si tu veux les executer chaque frame mais pour le faire 1x personne va capter que c'est lent
le problème que tu décris toi viens du fonctionnement du buffer:
les pixels prennent automatiquement un canal alpha à 0 une fois dans le buffer, et la psp n'en tiens pas compte lors du dessin et les dessine forcément avec un alpha à 255. c'est pour ca que quand tu swappe et reswappes, tous tes pixels ont un alpha à 0. ma fonction crée une copie du buffer mais remet le canal alpha à 255 sur tous les pixels. malheureusement ce n'est toujours pas ce que tu as besoin, si j'ai bien compris tu veux garder les infos de semi transparence, d'où mon idée de copier les pixels que t'as besoin directement d'une image à l'autre. comme ca tu utilises oslWriteImageFilePNG avec cette image et ca va marcher. bon après si tu veux du mélange de couleurs (dessin de pixels semi transparents sur d'autres pixels), là c'est ma fonction (lente) de dessin image sur image qui te sera utile.

eh ben quel paté je t'ai écris
__________________
Essayez mon dernier jeu sur iPhone:

daaa57150 est déconnecté   Réponse avec citation
Vieux 15/09/2008, 21h15   #5
Akabane87
Membre
 
Date d'inscription: 01/07/2008
Messages: 14
Par défaut

Merci pour tout daaa57150. J'ai regardé de près ta fonction et j'ai essayé de l'utiliser dans ma situation. Tout va bien (la vitesse me convient de mon cas), mais par contre ta méthode de calcul est fausse. Dans mon cas, j'avais nettoyé la surface cible avec RGBA(0,0,0,0) et je voulais afficher dessus une image avec de la semi transparence (le tout affiché sur un fond blanc à la fin). J'ai pu alors remarqué que ta méthode me fonçait tous mes pixels semi-transparents.
Et effectivement d'après ton calcul, c'est assez logique . J'ai donc corrigé ta fonction et maintenant elle fonctionne parfaitement .

Voilà le calcul en question:

Code:
if(a_sum>0)
{
    da_left=255.0f-fda; //dest alpha left
    sa_left=255.0f-fsa; //src alpha left
                    
    rr=(int)((fdr*fda + fsr*da_left)/255.0f);
    rg=(int)((fdg*fda + fsg*da_left)/255.0f);
    rb=(int)((fdb*fda + fsb*da_left)/255.0f);
    ra=255-(int)((da_left*sa_left)/255.0f);
    pixel8888result=RGBA(rr,rg,rb,ra);
}
ps: désolé, si je suis passé en C . En tout cas ça fonctionne, c'est sûr .
Akabane87 est déconnecté   Réponse avec citation
Vieux 15/09/2008, 21h30   #6
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

effectivement elle etait pas tout a fait juste j'avais aussi changé et ca donne ca chez moi a la fin:
Code PHP:
ra=sa + ((da_left*da)/255);
rr=(dr da_left sr sa) / ra;
rg=(dg da_left sg sa) / ra;
rb=(db da_left sb sa) / ra;
if(
ra>255)
    
ra=255;
if(
rr>255)
    
rr=255;
if(
rg>255)
    
rg=255;
if(
rb>255)
    
rb=255
le résultat est nickel mais j'ai dû vérifier que les canaux dépassent pas 255 ce qui veut dire que je me gourre un peu qqp, et donc j'avais pas posté (et puis c'est pas optimisé et je voulais pas me faire choper par nesgba, chuuut)...
mais l'essentiel c'est que ca marche, tu peux poster la tienne dans le thread draw image on image? comme ca ceux qui cherchent auront qqch de correct.
__________________
Essayez mon dernier jeu sur iPhone:

daaa57150 est déconnecté   Réponse avec citation
Vieux 15/09/2008, 22h23   #7
Akabane87
Membre
 
Date d'inscription: 01/07/2008
Messages: 14
Par défaut

lol t'inquiète pas, je te laisse toi même modifier ta fonction. Après tout, je n'ai fais que constater le problème, chercher un peu sur le net et trouver une formule qui s'est avérée fonctionner . Tout le mérite te revient .

En tout cas, je suis heureux que ma fonction de conversion de png fonctionne. J'ai juste encore un petit soucis parce que je veux directement écrire mon png sur l'ancien et que apparemment Bruni avait prévu le coup en protégeant ce cas. Tant pis, je vais devoir supprimer l'ancien png et et créer le nouveau avec le même nom .

edit: N'importe quoi je délire complètement, j'avais simplement oublié de mettre tous le chemin de l'image source et non pas juste le nom X_X. Tout fonctionne farpaitement bien .

Dernière modification par Akabane87 ; 15/09/2008 à 22h53.
Akabane87 est déconnecté   Réponse avec citation
Réponse

Liens sociaux

Publicité



Utilisateurs regardant la discussion actuelle : 1 (0 membre(s) et 1 invité(s))
 
Outils de la discussion
Modes d'affichage

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Navigation rapide

Discussions similaires
Discussion Auteur Forum Réponses Dernier message
NDS Flashage NDS v2 avec SuperCard Cruelo Articles et Tutos 138 24/02/2008 14h56
Wii [démenti du démenti] La manette de la revo compatible avec Zelda TP Costello Jeux 80 04/11/2006 17h32
NDS Questions d'un total NooB legoliades Archives - Divers (NDS) 9 19/01/2006 19h30
NDS flasher sa ds avec un m3 possible ou non? nicomic Linkers M3/R4 5 04/01/2006 12h39


Fuseau horaire GMT +2. Il est actuellement 04h04.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Tous droits réservés.
Version française #16 par l'association vBulletin francophone
Design par Ass-Itch, DJP et Dr.Vince