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 :D

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é :D

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 :P

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
:)