PNX

Programmation d'applications complexes
Shadow
Messages : 1373
Inscription : mer. 04/nov./2015 17:39

Re: PNX

Message 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
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Bernie
Messages : 282
Inscription : mar. 22/mars/2016 10:12
Localisation : En France

Re: PNX

Message 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 ,
Avatar de l’utilisateur
Ar-S
Messages : 9476
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: PNX

Message par Ar-S »

Tu chipotes Bernie..
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
TazNormand
Messages : 1294
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: PNX

Message 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)
Image
Image
Fred
Site Admin
Messages : 2652
Inscription : mer. 21/janv./2004 11:03

Re: PNX

Message 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.
Bernie
Messages : 282
Inscription : mar. 22/mars/2016 10:12
Localisation : En France

Re: PNX

Message par Bernie »

Moi perso je salue l'effort de shadow de montrer du code
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: PNX

Message par Micoute »

Et moi aussi.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre