Page 1 sur 2
LoadSprite et des fichiers avec et sans couche Alpha
Publié : mer. 29/avr./2009 18:34
par Thyphoon
J'ai un souci !
Dans une application j'ai une routine qui charge des sprites. mais voilà certain sont des fichier PNG normal et d'autre avec couche Alpha.
Or le problème c'est que dans un cas il faut faire
LoadSprite(NoSprite,Path,#PB_Sprite_Texture)
et dans l'autre
LoadSprite(NoSprite,Path,#PB_Sprite_Texture|#PB_Sprite_AlphaBlending)
Comment faire pour que ça charge l'image correctement qu'il y ai ou pas une couche Alpha ? je trouve bien dommage que ça ne se fasse pas automatique
si quelqu'un a une idée Merci
Thy
Publié : mer. 29/avr./2009 20:26
par Anonyme
2 possibilités par difficultés décroissante :
- Tu lis le header du png avec readfile() et tu détermines si il y a une couche alpha.
- Tu créer un fichier texte (.txt) avec le nom du fichier suivi d'un séparateur et d'un flag
ex :
MonImage.png%0
MonImage1.png%1
0 = pas d'alpha
1 = alpha
en fonction de la lecture , tu charges avec la fonction adéquat.
@+
Publié : mer. 29/avr./2009 21:11
par Thyphoon
Cpl.Bator a écrit :2 possibilités par difficultés décroissante :
- Tu lis le header du png avec readfile() et tu détermines si il y a une couche alpha.
- Tu créer un fichier texte (.txt) avec le nom du fichier suivi d'un séparateur et d'un flag
ex :
MonImage.png%0
MonImage1.png%1
0 = pas d'alpha
1 = alpha
en fonction de la lecture , tu charges avec la fonction adéquat.
@+
Tu as une idée comment détecté dans le header la couche a alpha ?
je vais essayer de trouver un descriptif du header du png ....
Edit (22h45): j'ai trouvé des trucs sur l'entête mais ça n'a pas l'air très simple pour savoir si il y a ou non couche alpha.Je regarderais demain...
Voici le lien :
http://wiki.multimedia.cx/index.php?title=PNG
Publié : mer. 29/avr./2009 23:01
par Anonyme
je me balade dans le fichier , mais je trouve pas l'info dans la structure qui dit que c'est en 32 bits ou 24 bits , même avec un éditeur héxa et un fichier de 1 pixel a analyser :/
j'arrive quand même a déterminer la taille
Code : Tout sélectionner
PNG$ = "test.png"
*PNG_HEADER = AllocateMemory(8)
PokeC(*PNG_HEADER,$89)
PokeC(*PNG_HEADER+1,$50)
PokeC(*PNG_HEADER+2,$4E)
PokeC(*PNG_HEADER+3,$47)
PokeC(*PNG_HEADER+4,$D)
PokeC(*PNG_HEADER+5,$A)
PokeC(*PNG_HEADER+6,$1A)
PokeC(*PNG_HEADER+7,$A)
If ReadFile(0,PNG$)
*PNG_HEADER_FILE = AllocateMemory(174)
ReadData(0,*PNG_HEADER_FILE,174)
; Vérification de la validité d'un png
For offset = 0 To 7
If PeekC(*PNG_HEADER_FILE+offset) <> PeekC(*PNG_HEADER+offset)
MessageRequester("Erreur","C'est pas un png valide")
EndIf
Next
Hexa$ = Hex(PeekL(*PNG_HEADER_FILE+16))
For i = 0 To 3
HexaRevert$ + Mid(Hexa$,4-i,1)
Next
PngWidth = Val("$"+HexaRevert$)
Hexa$ = Hex(PeekL(*PNG_HEADER_FILE+20))
HexaRevert$ = ""
For i = 0 To 3
HexaRevert$ + Mid(Hexa$,4-i,1)
Next
PngHeight = Val("$"+HexaRevert$)
A = 36
Hexa$ = "$"
For byte_offset = A To A+3
Byte.c = PeekC(*PNG_HEADER_FILE + byte_offset)
Hexa$ + RSet(Hex(byte),2,"0")
Next
Debug PngWidth
Debug PngHeight
CloseFile(0)
EndIf
Publié : jeu. 30/avr./2009 2:38
par case
bon j'ai regardé un peu la structure des fichiers png
et voila un code qui vous donne tout les blocks dans l'image en parcourant le fichier
Code : Tout sélectionner
; png structure
;
;
;
Debug" --"
Declare.s getchunk(file)
checkpng$=Chr(137)+Chr(80)+Chr( 78)+Chr( 71)+Chr( 13)+Chr( 10 )+Chr(26 )+Chr(10)
rd=ReadFile(#PB_Any,"test.png")
If rd
; check
For chk=1 To Len(checkpng$) ; check if the file is a png file
signature$=signature$+Chr(ReadByte(rd))
Next
;
If signature$=checkpng$
Debug "(image png)"
Repeat
ln.q=0
For a=1 To 4
v=ReadByte(rd) &$ff
PokeB(@ln+4-a,v)
Next
p$= getchunk(rd)
FileSeek(rd,Loc(rd)+ln)
crc.q=ReadLong(rd)
Debug " block "+ p$+" de "+Str(ln)+" octets - crc32 : "+Str(crc)
Until Eof(rd)
Else
Debug"format inconnu"
EndIf
CloseFile(rd)
EndIf
Procedure.s getchunk(file)
For get=1 To 4
chunk$=chunk$+Chr(ReadByte(file))
Next
Debug "["+chunk$+"]"
ProcedureReturn chunk$
EndProcedure
la presence d'une couche de transparence est indiquée par la présence d'un bloc tRNS
voici un exemple de sortie d'une image contenant une couche alpha
--
(image png)
[IHDR]
block IHDR de 13 octets - crc32 : -240707475
[PLTE]
block PLTE de 591 octets - crc32 : -589850203
[tRNS]
block tRNS de 192 octets - crc32 : -1816015277
[bKGD]
block bKGD de 1 octets - crc32 : -518321132
[IDAT]
block IDAT de 275 octets - crc32 : 1738474954
[IEND]
block IEND de 0 octets - crc32 : -2107620690
le meme sur une image n'ayant pas de transparence
--
(image png)
[IHDR]
block IHDR de 13 octets - crc32 : 2043993194
[pHYs]
block pHYs de 9 octets - crc32 : 412916224
[iCCP]
block iCCP de 2639 octets - crc32 : -617794717
[gAMA]
block gAMA de 4 octets - crc32 : -1823343748
[cHRM]
block cHRM de 32 octets - crc32 : 1187340178
[IDAT]
block IDAT de 839969 octets - crc32 : 1716754465
[IEND]
block IEND de 0 octets - crc32 : -2107620690
reste plus qu'a faire un select / case en fonction du bloc et a décoder chaque partie du fichier
j'espere que ca fait avancer le schmilblic

Publié : jeu. 30/avr./2009 4:14
par Ollivier
Ici, il y a des infos sur le PNG.
Code : Tout sélectionner
ReadFile(0, OpenFileRequester("", "", "*.PNG", 0) )
FileSeek(0, 25)
If ReadByte(0) = 6: Debug "Couche alpha": EndIf
CloseFile(0)
Publié : jeu. 30/avr./2009 5:23
par Thyphoon
Merci les gars je vais tester ça ! mais j'avoue ne toujours pas comprendre pourquoi Fred n'a pas inclu se test dans la function loadsprite !
Je vais tester ça dans la matiné ....mon bus m'attends pour l'instant
Publié : jeu. 30/avr./2009 7:53
par Thyphoon
ça marche apparemment super ! j'ai utiliser le code d'Ollivier qui est le plus rapide, mais le code de Case marche aussi.
Voici la procedure que je me suis fait pour ne plus avoir besoin de me poser de question
Code : Tout sélectionner
;************************
;Chargement d'une image PNG avec et sans Alpha
;Merci a Ollivier, Case et Cpl.Bator
;source : http://www.purebasic.fr/french/viewtopic.php?p=97059#97059
;************************
Procedure LoadSprite3DAlphaAuto(NoSprite.l,Filename.s,Option.l)
If LCase(GetExtensionPart(Filename.s))="png" And ReadFile(0, Filename.s )
FileSeek(0, 25)
If ReadByte(0) = 6
Debug "Couche alpha"
Option.l=Option|#PB_Sprite_AlphaBlending;
EndIf
CloseFile(0)
EndIf
If LoadSprite(NoSprite,Filename,Option) and CreateSprite3D(NoSprite,NoSprite)
ProcedureReturn #True
Else
ProcedureReturn #False
Endif
EndProcedure
Si vous avez des idées ou des suggestions pour l'ameliorer... En tout cas moi ça me simplifie la vie... Un grand merci a vous !
Publié : jeu. 30/avr./2009 9:59
par case
autant pour moi, la méthode d'ollivier est la plus simple et surtout la plus fiable , j'étais passe a cote de ça
ceci dit mon code peut etre utile si on veux acceder a certains blocs

Publié : jeu. 30/avr./2009 10:02
par Thyphoon
case a écrit :autant pour moi, la méthode d'ollivier est la plus simple et surtout la plus fiable , j'étais passe a cote de ça
ceci dit mon code peut etre utile si on veux acceder a certains blocs

J'ai mis ton code de côté car il me permet de récupérer d'autre info qui m'intéresse ! tu es le champion des entêtes de fichier, tu m'avais déjà sauvé avec les entêtes des fichiers icons Amiga il y a quelques temps...
Encore merci pour le temps investit !
Publié : jeu. 30/avr./2009 12:39
par Anonyme
Arggg , j'ai pourtant cherché à quoi correspond se fameux offset 25 , je suis passé à coté

Publié : jeu. 30/avr./2009 13:28
par Thyphoon
Est-ce quelqu'un pourrait m'expliquer ou dans la documentation on parle de l'offset 25 .. j'ai beau chercher j'ai pas trouver...et j'aimerais essayer d'être moins c** lorsque j'essaye de comprendre les entêtes de fichier

Publié : jeu. 30/avr./2009 14:08
par djes
Franchement, si dès le départ tu ne fais pas la distinction entre les sprites avec ou sans couche alpha, je pense que tu vas avoir des problèmes par la suite. Mais c'est vrai qu'un truc qui te dit automatiquement s'il y en a une, ça peut être utile

Publié : jeu. 30/avr./2009 14:35
par Thyphoon
djes a écrit :Franchement, si dès le départ tu ne fais pas la distinction entre les sprites avec ou sans couche alpha, je pense que tu vas avoir des problèmes par la suite. Mais c'est vrai qu'un truc qui te dit automatiquement s'il y en a une, ça peut être utile

Moi je le sais, le problème c'est j'ai créer une appli pour le boulot, une sorte de borne interactive. Et n'importe qui peut être amené a refaire les ecrans. Mettre une image ici et là, un logo, un cache, etc...et eux ne savent pas ce qu'est une couche alpha. là maintenant ça marche super !!!
Publié : jeu. 30/avr./2009 14:48
par djes