Page 1 sur 2

PNX

Publié : mer. 30/mars/2016 20:53
par Shadow
Bonsoir,

Voici un format d'image créer par moi même.

PNX n'est qu'un nom pris parce que j'aime bien son style, ne pas confondre avec le vraie format qui n'est pas de moi.
Ce nom est provisoire surement.

Ceci est un premier Jet, il fonctionne, en 64 bits sûr, 32 je ne sais pas.
Il n'est pas mieux que PNG, moins bien même mais ça va pas m’arrêter pour autant.

Voici le codeur:

Code : Tout sélectionner

; Code créer par monsieur Dieppedalle David le 30/03/2016.
; Code une image au format PNX (Nom choisir pour son style, ne pas se fier à ses initiales).

; Principe de fonctionnement (Simplifié).
; Remplace les successions de pixels identiques qui se suivent par un code plus court.
; Ex: RGB(125, 47, 75), RGB(125, 47, 75), RGB(125, 47, 75), RGB(125, 47, 75) = RGB(125, 47, 75), Octets 0, RGB(3, 0, 0) (Nombre de répétition de la couleur sur 3 octets, ne prends pas en compte le premier)

Global NomFichierImage$

; Procedure de chargement d'une image
Procedure.l ChargementImage(NumeroImage.i, FiltreDefaut.i)
  
  Filtre$ = "Image Bmp (*.Bmp)|*.Bmp|Image Png (*.Png)|*.Png|Image Jpg (*.Jpg)|*.Jpg|Image Tga (*.Tga)|*.Tga|Image Tiff (*.Tiff)|*.Tiff"
  FichierImage$ = OpenFileRequester("Choisissez un fichier image à charger...", GetHomeDirectory() + "Bureau\", Filtre$, FiltreDefaut.i)
  NomFichierImage$ = GetFilePart(FichierImage$, #PB_FileSystem_NoExtension)
  
  If FichierImage$
    
    Select LCase(GetExtensionPart(FichierImage$))
        
      Case  "bmp"
        ; Ok
        
      Case "png"
        UsePNGImageDecoder()
        
      Case "jpeg","jpg"
        UseJPEGImageDecoder()
        
      Case  "tga"
        UseTGAImageDecoder()
        
      Case "tiff"
        UseTIFFImageDecoder()
        
      Default
        MessageRequester("Fichier invalide !", "      Veuillez choisir un fichier d'image valide !", 48)
        
        ProcedureReturn 0
        
    EndSelect
    
    If LoadImage(NumeroImage.i, FichierImage$) <> 0
      ProcedureReturn LoadImage(NumeroImage.i, FichierImage$)
    Else
      MessageRequester("Erreur de chargement !", "      Impossible de charger le fichier " + Chr(34) + GetFilePart(FichierImage$) + Chr(34) + " !", 16)
      ProcedureReturn 0
    EndIf
    
  EndIf
  
  ProcedureReturn 0
EndProcedure

Macro CodeCouleur()
  
  If Compteur.q > 2 ; Si le nombre de pixel de même couleur comptabilisé (Qui se suivent) est plus grand que 2 (3 Mini).
    
    ; Si la profondeur de l'image est plus petit que 32.
    If ProfondeurImage.i < 32
      
      ; Ont écris dans le fichier les composantes de la couleur (La couleur) sur 3 octets (1 octets par composante).
      WriteAsciiCharacter(1, Red(SauvegardeCouleur.q))
      WriteAsciiCharacter(1, Green(SauvegardeCouleur.q))
      WriteAsciiCharacter(1, Blue(SauvegardeCouleur.q))
      
      ; Ont écris ensuite dans le fichier un octets 0, il servira à indiquer que la couleur précédente se répète au nombre des 3 octets qui suivent.
      ; Cet octet 0 sert d'indicateur.
      WriteAsciiCharacter(1, 0)
      
      ; Ont écris dans le fichier le nombre de fois que la couleur se répète, attention, ont ne compte pas la première couleur (Le premier pixel).
      ; Ont code ça sur 3 octets, le nombre de répétition de la couleur est codé en tant que couleur (RGB), pour être sur 3 octets, 4 c'est trop.
      WriteAsciiCharacter(1, Red(Compteur.q - 1))
      WriteAsciiCharacter(1, Green(Compteur.q - 1))
      WriteAsciiCharacter(1, Blue(Compteur.q - 1))
      
      ; Sinon Si la profondeur de l'image est égale à 32.
    ElseIf ProfondeurImage.i = 32
      
      ; Ont écris dans le fichier les composantes de la couleur (La couleur) sur 4 octets (1 octets par composante).
      WriteAsciiCharacter(1, Red(SauvegardeCouleur.q))
      WriteAsciiCharacter(1, Green(SauvegardeCouleur.q))
      WriteAsciiCharacter(1, Blue(SauvegardeCouleur.q))
      WriteAsciiCharacter(1, Alpha(SauvegardeCouleur.q))
      
      ; Ont écris ensuite dans le fichier un octets 0, il servira à indiquer que la couleur précédente se répète au nombre des 3 octets qui suivent.
      ; Cet octet 0 sert d'indicateur.
      WriteAsciiCharacter(1, 0)
      
      ; Ont écris dans le fichier le nombre de fois que la couleur se répète, attention, ont ne compte pas la première couleur (Le premier pixel).
      ; Ont code ça sur 3 octets, le nombre de répétition de la couleur est codé en tant que couleur (RGB), pour être sur 3 octets, 4 c'est trop.
      WriteAsciiCharacter(1, Red(Compteur.q - 1))
      WriteAsciiCharacter(1, Green(Compteur.q - 1))
      WriteAsciiCharacter(1, Blue(Compteur.q - 1))
      
    EndIf
    
    ; Ont remet le compteur à 1.
    Compteur.q = 1
    
    ; Ont sauvegarde la couleur actuel car c'est une couleur différente.
    SauvegardeCouleur.q = Couleur.q
    
  Else ; Sinon Si le nombre de pixel de même couleur comptabilisé (Qui se suivent) est plus petit que 3 (1 ou 2 par exemple).
    
    ; Si ont ne se trouve pas au tout début de l'image, X-0, Y-0.
    If X.i <> 0 Or Y.i <> 0
      
      ; Si la profondeur de l'image est plus petit que 32.
      If ProfondeurImage.i < 32
        
        For I = 1 To Compteur.q
          WriteAsciiCharacter(1, Red(SauvegardeCouleur.q))
          WriteAsciiCharacter(1, Green(SauvegardeCouleur.q))
          WriteAsciiCharacter(1, Blue(SauvegardeCouleur.q))
        Next
        
        ; Sinon Si la profondeur de l'image est égale à 32.
      ElseIf ProfondeurImage.i = 32
        
        For I = 1 To Compteur.q
          WriteAsciiCharacter(1, Red(SauvegardeCouleur.q))
          WriteAsciiCharacter(1, Green(SauvegardeCouleur.q))
          WriteAsciiCharacter(1, Blue(SauvegardeCouleur.q))
          WriteAsciiCharacter(1, Alpha(SauvegardeCouleur.q))
        Next
        
      EndIf
      
    EndIf
    
  EndIf
  
EndMacro

#ImageSource = 1

NumeroImageSource.i = ChargementImage(#ImageSource, 1)

If NumeroImageSource.i 
  
  If IsImage(#ImageSource)
    
    CreateFile(1, NomFichierImage$ + ".pnx")
    
    ; Obtension de la Largeur de l'image.
    LargeurImage.i = ImageWidth(#ImageSource)
    
    ; Obtension de la Hauteur de l'image.
    HauteurImage.i = ImageHeight(#ImageSource)
    
    ; Obtension de la Profondeur de l'image.
    ProfondeurImage.i = ImageDepth(#ImageSource)
    
    WriteWord(1, LargeurImage.i) ; Ecris la Largeur de l'image sur 2 octets.
    WriteWord(1, HauteurImage.i) ; Ecris la Hauteur de l'image sur 2 octets.
    WriteAsciiCharacter(1, ProfondeurImage.i) ; Ecris la Proifondeur de l'image sur 1 octets.
    
    SauvegardeCouleur.q = -1
    Compteur.q = 1
    
    StartDrawing(ImageOutput(#ImageSource))
    
    If ProfondeurImage.i = 32
      DrawingMode(#PB_2DDrawing_AlphaBlend)
    EndIf
    
    For Y.i = 0 To HauteurImage.i - 1
      
      For X.i = 0 To LargeurImage.i - 1
        
        ; Obtension de la couleur du pixel lue actuellement.
        Couleur.q = Point(X.i, Y.i)
        
        ; Obtension des composantes de la couleur.
        Rouge.i = Red(Couleur.q)
        Vert.i = Green(Couleur.q)
        Bleu.i = Blue(Couleur.q)
        Alpha.i = Alpha(Couleur.q)
        
        ; Si Rouge = 0, alors Rouge sera 1 car 0 est réservé.
        If Rouge.i = 0
          Rouge.i = 1
        EndIf
        
        ; Si Vert = 0, alors Vert sera 1 car 0 est réservé.
        If Vert.i = 0
          Vert.i = 1
        EndIf
        
        ; Si Bleu = 0, alors Bleu sera 1 car 0 est réservé.
        If Bleu.i = 0
          Bleu.i = 1
        EndIf
        
        ; Si Alpha = 0, alors Alpha sera 1 car 0 est réservé.
        If Alpha.i = 0
          Alpha.i = 1
        EndIf
        
        ; Modification de la couleur avec les nouvelle données.
        
        ; Si la profondeur de l'image est plus petit que 32.
        If ProfondeurImage.i < 32
          Couleur.q = RGB(Rouge.i, Vert.i, Bleu.i)
          
          ; Sinon Si la profondeur de l'image est égale à 32.
        ElseIf ProfondeurImage.i = 32
          Couleur.q = RGBA(Rouge.i, Vert.i, Bleu.i, Alpha.i)
          
        EndIf
        
        ; Si la couleur sauvegardé précédément est la même que celle lut actuellement.
        If SauvegardeCouleur.q = Couleur.q
          Compteur.q + 1 ; Ont ajoute 1 au compteur de répétition de la couleur.
          
          ; Par contre Si la couleur sauvegardé précédément est différente de celle lut actuellement.
        ElseIf SauvegardeCouleur.q <> Couleur.q
          CodeCouleur()
          
          SauvegardeCouleur.q = Couleur.q
          Compteur.q = 1
          
        Else ; Sinon Si ont se trouve au tout début de l'image, X-0, Y-0.
          
          ; Ont sauvegarde la couleur actuel car c'est une couleur différente.
          SauvegardeCouleur.q = Couleur.q
          
          Continue ; Ont continue la boucle, comme ont est au tout début de l'image, la couleur sauvegardé (= -1) est forcement différente de la couleur lut actuellement.
          
        EndIf
        
        If X.i = LargeurImage.i - 1 And Y.i = HauteurImage.i - 1
          CodeCouleur()
          
        EndIf
        
      Next
      
    Next
    
  EndIf
  
  StopDrawing()
  CloseFile(1)
  
EndIf

Le décodeur:

Code : Tout sélectionner

; Code créer par monsieur Dieppedalle David le 30/03/2016.
; Décode un fichier PNX.

Fichier$ = OpenFileRequester("Sélectionnez un fichier","","Fichier Pnx (.pnx)|*.pnx",0)
NomFichierImage$ = GetFilePart(Fichier$, #PB_FileSystem_NoExtension)

If Fichier$
  
  If ReadFile(0, Fichier$) 
    
    ; Lit la Largeur de l'image sur 2 octets.
    LargeurImage.i = ReadWord(0)
    
    ; Lit la Hauteur de l'image sur 2 octets.
    HauteurImage.i = ReadWord(0)
    
    ; Lit la Profondeur de l'image sur 1 octets.
    ProfondeurImage.i = ReadAsciiCharacter(0)
    
    X.i = 0
    Y.i = 0
    
    ; Si la profondeur de l'image est plus petit que 32.
    If ProfondeurImage.i < 32
      
      ; Création de l'image 24 bits de sortie.
      CreateImage(1, LargeurImage.i, HauteurImage.i, ProfondeurImage.i, RGB(255, 255, 255))
      StartDrawing(ImageOutput(1))

      ; Sinon Si la profondeur de l'image est égale à 32.
    ElseIf ProfondeurImage.i = 32
      
      ; Création de l'image 32 bits de sortie.
      CreateImage(1, LargeurImage.i, HauteurImage.i, ProfondeurImage.i, #PB_Image_Transparent )
      StartDrawing(ImageOutput(1))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      
    EndIf
    
    ; Lit le reste du fichier.
    While Eof(0) = 0
      
      ; Lecture du prochain caractères Ascii (Numéro).
      CaractereAscii.i = ReadAsciiCharacter(0)
      
      ; Si la valeur Ascii du caractère est supérieur à 0.
      If CaractereAscii.i > 0
        
        ; C'est la première composante d'une couleur qu'ont viens de lire.
        Rouge.i = CaractereAscii.i
        
        ; Si la profondeur de l'image est plus petit que 32.
        If ProfondeurImage.i < 32
          
          ; Lit les deux prochain caractères Ascii 
          
          ; Lecture du prochain caractères Ascii (Numéro).
          CaractereAscii.i = ReadAsciiCharacter(0)
          
          ; C'est la deuxième composante d'une couleur qu'ont viens de lire.
          Vert.i = CaractereAscii.i
          
          ; Lecture du prochain caractères Ascii (Numéro).
          CaractereAscii.i = ReadAsciiCharacter(0)
          
          ; C'est la troixième composante d'une couleur qu'ont viens de lire.
          Bleu.i = CaractereAscii.i
          
          ; Sauvegarde de la couleur 24 bits lut actuellement.
          SauvegardeCouleur.q = RGB(Rouge.i, Vert.i, Bleu.i)
          
          ; Déssine la couleur du pixel sur l'image.
          Plot(X.i, Y.i, SauvegardeCouleur.q)
          
          If X.i < LargeurImage.i - 1
            X.i + 1
            
          ElseIf X.i = LargeurImage.i - 1
            X.i = 0
            Y.i + 1
            
          EndIf
          
          ; Sinon Si la profondeur de l'image est égale à 32.
        ElseIf ProfondeurImage.i = 32
          
          ; Lit les trois prochain caractères Ascii 
          
          ; Lecture du prochain caractères Ascii (Numéro).
          CaractereAscii.i = ReadAsciiCharacter(0)
          
          ; C'est la deuxième composante d'une couleur qu'ont viens de lire.
          Vert.i = CaractereAscii.i
          
          ; Lecture du prochain caractères Ascii (Numéro).
          CaractereAscii.i = ReadAsciiCharacter(0)
          
          ; C'est la troixième composante d'une couleur qu'ont viens de lire.
          Bleu.i = CaractereAscii.i
          
          ; Lecture du prochain caractères Ascii (Numéro).
          CaractereAscii.i = ReadAsciiCharacter(0)
          
          ; C'est la quatrième composante d'une couleur qu'ont viens de lire.
          Alpha.i = CaractereAscii.i
          
          ; Sauvegarde de la couleur 32 bits lut actuellement.
          SauvegardeCouleur.q = RGBA(Rouge.i, Vert.i, Bleu.i, Alpha.i)
          
          ; Déssine la couleur du pixel sur l'image.
          Plot(X.i, Y.i, SauvegardeCouleur.q)
          
          If X.i < LargeurImage.i - 1
            X.i + 1
            
          ElseIf X.i = LargeurImage.i - 1
            X.i = 0
            Y.i + 1
            
          EndIf
          
        EndIf
        
        ; Sinon Si la valeur Ascii du caractère est égale à 0.
      ElseIf CaractereAscii.i = 0
        
        ; Lit les 3 prochain Caractère Ascii pour savoir le nombre de fois que se répète la couleur
        
        ; Lecture du prochain caractères Ascii (Numéro).
        CaractereAscii.i = ReadAsciiCharacter(0)
        
        ; C'est le premier octets du nombre de répétition de la couleur.
        Octets1.i = CaractereAscii.i
        
        ; Lecture du prochain caractères Ascii (Numéro).
        CaractereAscii.i = ReadAsciiCharacter(0)
        
        ; C'est le deuxième octets du nombre de répétition de la couleur.
        Octets2.i = CaractereAscii.i
        
        ; Lecture du prochain caractères Ascii (Numéro).
        CaractereAscii.i = ReadAsciiCharacter(0)
        
        ; C'est le troixième octets du nombre de répétition de la couleur.
        Octets3.i = CaractereAscii.i
        
        For I = 1 To RGB(Octets1.i, Octets2.i, Octets3.i)
          
          ; Déssine la couleur du pixel sur l'image.
          Plot(X.i, Y.i, SauvegardeCouleur.q)
          
          If X.i < LargeurImage.i - 1
            X.i + 1
            
          ElseIf X.i = LargeurImage.i - 1
            X.i = 0
            Y.i + 1
            
          EndIf
          
        Next
        
      EndIf
      
    Wend
    
    CloseFile(0)
    StopDrawing()
    
    UsePNGImageEncoder()
    SaveImage(1, NomFichierImage$ + " Sortie.png", #PB_ImagePlugin_PNG, ProfondeurImage.i)
    
  EndIf
  
EndIf
Note: Il faut ensuite compresser le fichier de sortie PNX avec 7zip par exemple.

Re: PNX

Publié : mer. 30/mars/2016 21:18
par falsam
Note: Il faut ensuite compresser le fichier de sortie PNX avec 7zip par exemple.
Si tu le compresses avec 7Zip ou autre il y aura l'extension du compresseur et non pas .pnx

Hors ton décodeur cherche un .pnx

j'ai tel le noob moyen renommer le fichier en pnx et le décodeur c'est planté :wink:

Re: PNX

Publié : mer. 30/mars/2016 21:28
par Shadow
Ah ah, non.

Il faut compresser le fichier PNX avec 7 zip mais le décompresser aussi avec 7zip et ensuite le passé au décodeur.
Je sais, c'est pas se qui à de mieux mais je cherche.

Re: PNX

Publié : mer. 30/mars/2016 21:31
par venom
Pourquoi ne te sert tu pas de la lib Packer Comme sa tu peut faire une interface graphique qui ziperait / dezipperait directement ? Et le tout en PB.






@++

Re: PNX

Publié : mer. 30/mars/2016 21:33
par Bernie
Shadow a écrit :Ah ah, non.

Il faut compresser le fichier PNX avec 7 zip mais le décompresser aussi avec 7zip et ensuite le passé au décodeur.
Je sais, c'est pas se qui à de mieux mais je cherche.
MDR tu te complique vraiment la vie pourquoi tu veux compresser ton image dans un zip

Re: PNX

Publié : mer. 30/mars/2016 21:36
par GallyHC
Bernie > Pas avec Zip mais SevenZip (7Zip).

Re: PNX

Publié : mer. 30/mars/2016 21:37
par Shadow
venom a écrit :Pourquoi ne te sert tu pas de la lib Packer Comme sa tu peut faire une interface graphique qui ziperait / dezipperait directement ? Et le tout en PB.
Oui.... mais moins efficace que 7zip, c'est pour ça.

Re: PNX

Publié : mer. 30/mars/2016 21:43
par falsam
Compresser puis décompresser pour utiliser ton décodeur j'avoue que je ne comprend pas trop mais je l'ai fait pour voir ce que ça donne.

Png de départ 22 Ko
-Codage du Png -> Pnx 236 Ko

- Compression du PNX avec 7Zip
- Décompression du 7Z -> Pnx toujours 236 Ko ce qui est normal

- Décodage du Pnx -> Png 20 Ko (2 kilo de perdu)

Les codes sont bien documentés

Re: PNX

Publié : mer. 30/mars/2016 21:51
par Shadow
Je ne sais pas pourquoi l'image de sortie est moins grande mais c'est pas ça qui faut voir, c'est le pois de l'archive !

J'ai fais des test et mon format est BEAUCOUP plus performant avec des images qui contiennent beaucoup de couleurs identiques qui se suivent.
Même avec PNGGauntlet, je le bas haut la main.

Pour les autre image non, je suis loin d'avoir dis mon dernier mot.

Re: PNX

Publié : mer. 30/mars/2016 22:00
par venom
J'ai une erreur ligne 155 apres avoir choisi un png.
Le #File spécifié n'est pas initialisé.







@++

Re: PNX

Publié : mer. 30/mars/2016 22:02
par Shadow
Sans plus d'information, va être dur de savoir !

Re: PNX

Publié : mer. 30/mars/2016 22:04
par falsam
@Venom : Crée un dossier et enregistre les deux sources de Shadow ainsi que l'image à traité.

Re: PNX

Publié : mer. 30/mars/2016 22:12
par falsam
Shadow dans ton décodeur je pense que tu peux compresser le contenu du fichier en mémoire avant de recréer ton image.

Exemple de code

Code : Tout sélectionner

String$ ="Exemple d'un string en mémoire "

*InPut  = AllocateMemory(5000)
*OutPut = AllocateMemory(5000)

;Ecrit la chaîne de caractères à l'adresse *InPut
PokeS(*InPut, String$)
Debug "Taille avant compression " + MemorySize(*Input)

;Compresse le contenu de la mémoire tampon *InPut dans une mémoire tampon *OutPut.
Size =  CompressMemory(*InPut, MemorySize(*InPut), *OutPut, MemorySize(*OutPut), #PB_PackerPlugin_Lzma) 
Debug "Taille aprés compression " + Size

;Comment est compressée string$
ShowMemoryViewer(*OutPut, Size)

;Décompresse le contenu de la mémoire tampon *OutPut dans la mémoire tampon *InPut.
Size = UncompressMemory(*OutPut, MemorySize(*OutPut), *InPut, MemorySize(*InPut), #PB_PackerPlugin_Lzma)
Debug "Taille aprés décompression "+ Size

;Decommente l'instruction qui suit pour voir le résultat aprés décompression
;ShowMemoryViewer(*Input, Size)

FreeMemory(*InPut)
FreeMemory(*Output)

Re: PNX

Publié : mer. 30/mars/2016 22:22
par venom
Merci falsam ça fonctionne. :wink:

C'est drôle que ton codeur sort un pnx plus gros que le png d'origine :)





@++

Re: PNX

Publié : jeu. 31/mars/2016 3:07
par Shadow
venom a écrit :Merci falsam ça fonctionne. :wink:

C'est drôle que ton codeur sort un pnx plus gros que le png d'origine :)
Oui c'est vraie... mais il ne faut pas oublier que le PNG est compresser, alors que moi non !