Sauvegarder une image TGA

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Sauvegarder une image TGA

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

Message 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.
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

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

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

Message par djes »

Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

Merci beaucoup! :D
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message 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 ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message 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 :)
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

OK! Merci du tuyau!
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

C'est gentil de partager :)
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

Message par cha0s »

si tu veut ne pas utiliser d'api Windows (portabilité powa):
http://www.purebasic.fr/french/viewtopic.php?t=6092
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message 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.
Répondre