Page 1 sur 1

Sauvegarder une image TGA

Publié : jeu. 15/mai/2008 17:18
par Octavius
Les TGA sont maintenant faciles à ouvrir avec UseTGAImageDecoder()

Le problème c'est que si on veut modifier l'image et la ré-enregistrer, il n'y a pas de constante #PB_ImagePlugin_TGA disponible avec SaveImage(). Ma question est donc simple : comment faire ?

J'ai cherché un peu sur ce problème avant de poser la question mais je suis pas un expert des formats d'image (apparemment ya une histoire de compression et de couche alpha)

Pour info, les images TGA que je veux modifier sont au format 24 bits, ne contiennent pas de couche alpha (juste les trois couleurs RVB), sont de petite taille (entre 150 Ko et 700 Ko) et ne sont a priori pas compressées RLE (mais je ne sais pas comment le vérifier).

Publié : jeu. 15/mai/2008 20:07
par djes
Tu as vraiment besoin du format targa? Pourquoi tu n'enregistres pas en png? C'est un format lossless bien plus moderne.
Sinon le targa est très bien documenté partout, il est très facile de faire un "enregistreur" non compressé tout seul; en une demi-heure ça devrait être fait.

Publié : jeu. 15/mai/2008 20:14
par Octavius
Oui j'ai vraiment besoin du tga, c'est pour faire un éditeur de carte pour un jeu vidéo, le format m'est donc imposé.

J'ai pas trouvé de code pour créer un enregistreur, si c'est facile pour toi peut-être as-tu une idée de la façon dont je devrais m'y prendre ?

Publié : jeu. 15/mai/2008 21:28
par djes
regarde là : http://local.wasp.uwa.edu.au/~pbourke/dataformats/tga/
et là : http://www.martinreddy.net/gfx/2d/TGA.txt

tu as un exemple de code en C, il suffit de balancer un entête majoritairement composé de 0, puis la taille (largeur et hauteur), puis les composantes de l'image.

Sinon, je crois que progi1984 a fait un wrapper pour une bibliothèque pour lire plusieurs formats... Freeimage si je me souviens bien, mais je ne sais si elle lit les targa.

Publié : jeu. 15/mai/2008 21:29
par djes

Publié : jeu. 15/mai/2008 21:43
par Octavius
Merci beaucoup! :D

Publié : lun. 23/juin/2008 1:30
par Octavius
Voilà la procédure que j'ai mise au point pour enregistrer des images au format TGA. J'ai essayé de l'optimiser pour qu'elle soit assez rapide.

Code : Tout sélectionner

Structure pixel : Color.l : EndStructure

Procedure SaveTGA(Image.l,File$)
  Protected *Memory,*Address,X.l,Y.l,Color.l
  Protected Width.l,Height.l,bmp.BITMAP,*Image,*Pixel.pixel
  
  ;Dimensions de l'image
  Height=ImageHeight(Image)
  Width=ImageWidth(Image)
  
  ;Allocation mémoire pour enregistrer le TGA
  *Memory=AllocateMemory(ImageWidth(Image)*ImageHeight(Image)*3)
  *Address=*Memory
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp) : *Image=bmp\bmBits
  
  For X=0 To Height-1
    For Y=0 To Width-1
      ;Adresse du pixel
      *Pixel=*Image+Y*4+X*4*Width
      ;Couleur du pixel
      Color=*Pixel\Color
      ;Ecriture des octets de couleur
      PokeB(*Memory,Red(Color))
      *Memory+1
      PokeB(*Memory,Green(Color))
      *Memory+1
      PokeB(*Memory,Blue(Color))
      *Memory+1
    Next Y
  Next X
  
  ;Création du fichier
  CreateFile(#File,File$)
  
  ;Entête du fichier
  WriteByte(#File,0)
  WriteByte(#File,0)
  WriteByte(#File,2)
  
  WriteWord(#File,0)
  WriteWord(#File,0)
  WriteByte(#File,0)
  
  WriteWord(#File,0)
  WriteWord(#File,0)
  
  WriteWord(#File,Width)
  WriteWord(#File,Height)
  
  WriteByte(#File,24)
  WriteByte(#File,0)
  
  ;Ecriture des données
  WriteData(#File,*Address,Width*Height*3)
  
  ;Libération de la mémoire
  FreeMemory(*Address)
    
EndProcedure
PS : Il y a encore quelques petites améliorations à faire, pour l'instant je ne tient pas compte de la profondeur, seules les images en 32 bits peuvent être enregistrée (donc pas celles qui sont chargées avec LoadImage(), etc.). Les TGAs qui sont créés sont en 24 bits (pas de transparence). Le fichier comporte une entête minimale et aucun pied.

PS2 : Avec quelques petites améliorations ça pourrait devenir ma première petite bibliothèque ! :D

PS3 : Est-ce qu'on peut mettre des structures et des macros dans des libs ?

Publié : lun. 23/juin/2008 7:21
par Backup
Octavius a écrit : PS3 : Est-ce qu'on peut mettre des structures et des macros dans des libs ?

oui ! :)

tu as plusieurs solutions, soit tu met ta structure dans la proceduredll

soit tu met ta structure au debut du code :)

et j'ai apris recement qu'on pouvais meme avoir des procedures, dans une librairie

une proceduredll (celle qui contient la commande partagé avec l'exterieur de la lib ) peut faire appel a des procedures , qui elles ne seront pas partagé, et resteront pour l'usage interne de la librairie :)

Publié : lun. 23/juin/2008 9:41
par Octavius
OK! Merci du tuyau!

Publié : lun. 23/juin/2008 10:05
par djes
C'est gentil de partager :)

Publié : lun. 23/juin/2008 13:34
par cha0s
si tu veut ne pas utiliser d'api Windows (portabilité powa):
http://www.purebasic.fr/french/viewtopic.php?t=6092

Publié : lun. 23/juin/2008 13:56
par Octavius
Ah oui, avec les Point() et Plot() natifs, mais j'ai fait exprès d'utiliser mes propres fonctions (en utilisant certes l'API) pour augmenter la vitesse.