Page 2 sur 2

Re: PNX

Publié : jeu. 31/mars/2016 3:09
par Shadow
Nouvelle version, le fichier PNX est plus gros mais se compresse un peu mieux que la version précédente.

Code : Tout sélectionner

; Code créer par monsieur Dieppedalle David le 31/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 6 octets (2 octets par composante).
      WriteString(1, RSet(Hex(Red(SauvegardeCouleur.q)), 2, "0"))
      WriteString(1, RSet(Hex(Green(SauvegardeCouleur.q)), 2, "0"))
      WriteString(1, RSet(Hex(Blue(SauvegardeCouleur.q)), 2, "0"))
      
      ; Ont écris ensuite dans le fichier la valeur "00", elle servira à indiquer que la couleur précédente se répète au nombre des 6 octets qui suivent.
      ; Cette valeurt "00" sert d'indicateur.
      WriteString(1, "00")
      
      ; 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 6 octets, le nombre de répétition de la couleur est codé en tant que couleur (RGB), pour être sur 6 octets.
      
      WriteString(1, RSet(Hex(Red(Compteur.q - 1)), 2, "0"))
      WriteString(1, RSet(Hex(Green(Compteur.q - 1)), 2, "0"))
      WriteString(1, RSet(Hex(Blue(Compteur.q - 1)), 2, "0"))
      
      ; 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 8 octets (2 octets par composante).
      WriteString(1, RSet(Hex(Red(SauvegardeCouleur.q)), 2, "0"))
      WriteString(1, RSet(Hex(Green(SauvegardeCouleur.q)), 2, "0"))
      WriteString(1, RSet(Hex(Blue(SauvegardeCouleur.q)), 2, "0"))
      WriteString(1, RSet(Hex(Alpha(SauvegardeCouleur.q)), 2, "0"))
      
      ; Ont écris ensuite dans le fichier la valeur "00", elle servira à indiquer que la couleur précédente se répète au nombre des 6 octets qui suivent.
      ; Cette valeurt "00" sert d'indicateur.
      WriteString(1, "00")
      
      ; 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 6 octets, le nombre de répétition de la couleur est codé en tant que couleur (RGB), pour être sur 6 octets.
      
      WriteString(1, RSet(Hex(Red(Compteur.q - 1)), 2, "0"))
      WriteString(1, RSet(Hex(Green(Compteur.q - 1)), 2, "0"))
      WriteString(1, RSet(Hex(Blue(Compteur.q - 1)), 2, "0"))
      
    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
          WriteString(1, RSet(Hex(Red(SauvegardeCouleur.q)), 2, "0"))
          WriteString(1, RSet(Hex(Green(SauvegardeCouleur.q)), 2, "0"))
          WriteString(1, RSet(Hex(Blue(SauvegardeCouleur.q)), 2, "0"))
        Next
        
        ; Sinon Si la profondeur de l'image est égale à 32.
      ElseIf ProfondeurImage.i = 32
        
        For I = 1 To Compteur.q
          WriteString(1, RSet(Hex(Red(SauvegardeCouleur.q)), 2, "0"))
          WriteString(1, RSet(Hex(Green(SauvegardeCouleur.q)), 2, "0"))
          WriteString(1, RSet(Hex(Blue(SauvegardeCouleur.q)), 2, "0"))
          WriteString(1, RSet(Hex(Alpha(SauvegardeCouleur.q)), 2, "0"))
        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)
    
    WriteString(1, RSet(Hex(LargeurImage.i), 4, "0")) ; Ecris la Largeur de l'image sur 4 octets.
    WriteString(1, RSet(Hex(HauteurImage.i), 4, "0")) ; Ecris la Hauteur de l'image sur 4 octets.
    WriteString(1, RSet(Hex(ProfondeurImage.i), 2, "0")) ; Ecris la Proifondeur de l'image sur 2 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

Décodeur:

Code : Tout sélectionner

; Code créer par monsieur Dieppedalle David le 31/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 4 octets.
    LargeurImage.i = Val("$" + ReadString(0, #PB_Ascii, 4))
    
    ; Lit la Hauteur de l'image sur 4 octets.
    HauteurImage.i = Val("$" + ReadString(0, #PB_Ascii, 4))
    
    ; Lit la Profondeur de l'image sur 2 octets.
    ProfondeurImage.i = Val("$" + ReadString(0, #PB_Ascii, 2))
    
    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 de la prochaine valeur.
      Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
      
      ; Si la valeur est supérieur à 0.
      If Valeur.i > 0
        
        ; C'est la première composante d'une couleur qu'ont viens de lire.
        Rouge.i = Valeur.i
        
        ; Si la profondeur de l'image est plus petit que 32.
        If ProfondeurImage.i < 32
          
          ; Lit les quatre prochain caractères. 
          
          ; Lecture de la valeur suivante.
          Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
          
          ; C'est la deuxième composante d'une couleur qu'ont viens de lire.
          Vert.i = Valeur.i
          
          ; Lecture du prochain caractères Ascii (Numéro).
          Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
          
          ; C'est la troixième composante d'une couleur qu'ont viens de lire.
          Bleu.i = Valeur.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 six prochain caractères. 
          
          ; Lecture de la valeur suivante.
          Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
          
          ; C'est la deuxième composante d'une couleur qu'ont viens de lire.
          Vert.i = Valeur.i
          
          ; Lecture de la valeur suivante.
          Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
          
          ; C'est la troixième composante d'une couleur qu'ont viens de lire.
          Bleu.i = Valeur.i
          
          ; Lecture de la valeur suivante.
          Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
          
          ; C'est la quatrième composante d'une couleur qu'ont viens de lire.
          Alpha.i = Valeur.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 est égale à 0.
      ElseIf Valeur.i = 0
        
        ; Lit les 6 prochain Caractère pour savoir le nombre de fois que se répète la couleur.
        
        ; Lecture de la valeur suivante.
        Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
        
        ; C'est la première valeur du nombre de répétition de la couleur.
        Valeur1.i = Valeur.i
        
        ; Lecture de la valeur suivante.
        Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
        
        ; C'est la deuxième valeur du nombre de répétition de la couleur.
        Valeur2.i = Valeur.i
        
        ; Lecture de la valeur suivante.
        Valeur.i = Val("$" + ReadString(0, #PB_Ascii, 2))
        
        ; C'est la troixième valeur du nombre de répétition de la couleur.
        Valeur3.i = Valeur.i
        
        For I = 1 To RGB(Valeur1.i, Valeur2.i, Valeur3.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

Re: PNX

Publié : jeu. 31/mars/2016 6:37
par Bernie
Shadow
Filtre$ = "Image Bmp (*.Bmp)|*.Bmp|Image Png (*.Png)|*.Png|Image Jpg (*.Jpg)|*.Jpg|Image Tga (*.Tga)|*.Tga|Image Tiff (*.Tiff)|*.Tiff"
c'est JPEG et pas JPG ,

Re: PNX

Publié : jeu. 31/mars/2016 10:23
par Ar-S
Tu chipotes Bernie..

Re: PNX

Publié : jeu. 31/mars/2016 10:49
par TazNormand
Bien, on résume tout ça :
Un nouveau format qu'on va plutôt appeler "SHadow Image Type" avec l'extension *.shit pour éviter les problèmes avec le propriétaire du format PNX, et par hommage à Jean-Pierre COFFE :wink: .

Etape 1 :
  • je prends une image au format standard utilisé par tous les logiciels d'imagerie (PNG et JPG/JPEG)
    j'utilise l'outil de "ChasseDeau" pour transformer mon image originale en un fichier "monfichier.shit" plus gros et qu'aucun logiciel ne connaît
    je compresse avec 7zip, oups je télécharge 7zip
    j'installe 7zip
    je compresse donc avec 7zip
    J'obtiens donc un fichier plus "petit" grace à 7zip
Etape 2 :
  • Comme j'ai besoin de mon image pour quelconque raison (web, imprimer, montrer à quelqu'un...), je décompresse le fichier 7zip
    ah zut, l'image ne s'affiche pas dans ma page web/ma visionneuse ne connait pas le format *.shit
    Bon, j'utilise le "Deshitteur" de Shadow pour retrouver un PNG/JPG
    c'est presque bon, j'ai retrouver un fichier affichable, mais plus "petit", qu'est-ce qu'il a perdu en route ? Mystère et boule de gomme
Franchement, pour moi (je dis bien pour moi) :
  • intérêt ZÉRO
    Mise en place trop compliquée ("SHITteur"+7zip)

Re: PNX

Publié : jeu. 31/mars/2016 10:52
par Fred
Franchement, si un sujet ne vous intéresse pas, ne participez pas. Si il n'y a pas d’intérêt, le sujet mourra tout seul. Donc merci d'éviter les posts sans aucun rapport qui genèrent des hors-sujets.

Re: PNX

Publié : jeu. 31/mars/2016 16:07
par Bernie
Moi perso je salue l'effort de shadow de montrer du code

Re: PNX

Publié : jeu. 31/mars/2016 18:07
par Micoute
Et moi aussi.