LoadSprite et des fichiers avec et sans couche Alpha
LoadSprite et des fichiers avec et sans couche Alpha
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
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
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 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 ?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.
@+
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
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
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
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
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
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
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
voici un exemple de sortie d'une image contenant une couche alpha
le meme sur une image n'ayant pas de transparence--
(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
--
(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

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)
ç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
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 !
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
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...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
Encore merci pour le temps investit !
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 !!!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