LoadSprite et des fichiers avec et sans couche Alpha

Programmation d'applications complexes
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

LoadSprite et des fichiers avec et sans couche Alpha

Message 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
Anonyme

Message 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.

@+
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message 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
Anonyme

Message 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 
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Message 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 :)
ImageImage
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message 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)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message 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
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message 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 !
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Message 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 :)
ImageImage
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message 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 !
Anonyme

Message par Anonyme »

Arggg , j'ai pourtant cherché à quoi correspond se fameux offset 25 , je suis passé à coté :D
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message 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
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message 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 :)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message 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 !!!
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

:)
Répondre