Afficher un PNG sans décodeur PB

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Afficher un PNG sans décodeur PB

Message par Anonyme2 »

Un petit code qui permet de charger un fichier PNG ou un fichier icône avec une seule image compressée (qui est donc un PNG).

Le fichier chargé est une icône que l'on peut afficher avec les commandes PB classiques.
L'API CreateIconFromResourceEx est utilisée, cela devrait fonctionner depuis Vista car les icônes compressées n'existaient pas sur XP.

Changez les fichiers ico et PNG de l'exemple pour mettre les votre.
La procedure Load_PNG_to_Ico permet de charger soit un fichier ico compressé soit un fichier PNG.

Il suffit de changer la valeur du second paramètre.

Il faut détruire les icônes avec DestroyIcon_() lorsque ceux-ci ne sont plus indispensables.

J'utilise cette API depuis très longtemps pour les PNG.

Testé sous Seven et Win 10.

Code : Tout sélectionner

EnableExplicit
Define .i

Structure IconDirEntry
      ;// largeur de l'icône en pixels
      bWidth.a
      ;// hauteur de l'icône en pixels (x 2)
      bHeight.a
      ;// Ce champ permet d'indiquer le nombre de couleurs que prend en charge l'icône: 2, 4, 8 ou 16. Si la valeur est 0, il s'agit d'une icône de 256 couleurs ou plus.
      bColorCount.a ; nombre de couleurs de l'icône (0 si >=8bpp)
      ;// Ce champ est réservé, et il doit toujours contenir la valeur 0.
      bReserved.a
      ;// Ce champ permet d'indiquer le nombre de plages de couleurs que contient l'icône. (Color Planes)
      wPlanes.u
      ;// Ce champ permet d'indiquer le nombre de bits par pixel que contient l'icône. (Bits per pixel)
      wBitCount.u
      ;// Taille en octets de l'icône
      dwBytesInRes.l
      ;// Ce champ permet d'indiquer la position de déplacement (Offset), en octets, du début du fichiers jusqu'à l'icône.
      dwImageOffset.l
EndStructure
;- Structures IconDir
Structure IconDir
      idReserved.u ; réservé, toujours à 0
      idType.u ; resource type, à 1 pour les icônes
      idCount.u ; nombre d'image dans le fichier icônes
      idEntries.IconDirEntry[1] ; l'entrée de chaque image
EndStructure

#Fichier_Ico = 10

Procedure.i Load_PNG_to_Ico(Fichier$, Png = #True)
      ;// *********************************************************
      ;// Fichier$ avec chemin complet du fichier
      ;//
      ;// Png = #True     : Le fichier est un fichier Png
      ;// Png <> #True    : Le fichier est un fichier ico
      ;//                  avec une seule image compressée PNG
      ;//
      ;// Retoune le handle de l'icône ou -1 sinon
      ;//
      ;// *********************************************************
      
      ;// adresse du fichier png en mémoire
      Protected *MemoryAdd
      ;// mémorise la taille du fichier
      Protected Filesize_q
      ;// handle de l'icône
      Protected icon
      
      
      Filesize_q = FileSize(Fichier$)
      If Filesize_q < 0
            ProcedureReturn -1  ; erreur
      EndIf
      ;// Teste si fichier Png/ico
      If Not(((Png = #True) And (LCase(GetExtensionPart(Fichier$)) = "png")) Or
            (LCase(GetExtensionPart(Fichier$)) = "ico"))
            ProcedureReturn -1  ; erreur
      EndIf
      
      ;// allocation mémoire pour le fichier
      *MemoryAdd = AllocateMemory(Filesize_q)
      If *MemoryAdd = 0
            ProcedureReturn -1  ; erreur
      EndIf
      
      If ReadFile(#Fichier_Ico, Fichier$) = #Null
            FreeMemory(*MemoryAdd)
            ProcedureReturn -1  ; erreur
      EndIf
      
      ;// lecture et écriture du fichier en mémoire
      If ReadData(#Fichier_Ico, *MemoryAdd, Filesize_q) <> Filesize_q
            FreeMemory(*MemoryAdd)
            CloseFile(#Fichier_Ico)
            ProcedureReturn -1  ; erreur
      EndIf
      
      Select Png
            Case #True
                  icon = CreateIconFromResourceEx_(*MemoryAdd, Filesize_q, #True, $30000, 0, 0, 0)
            Case 0
                  icon = CreateIconFromResourceEx_(*MemoryAdd+SizeOf(IconDir), Filesize_q-SizeOf(IconDir), #True, $30000, 0, 0, 0)
      EndSelect
      
      ;// termine
      FreeMemory(*MemoryAdd)
      CloseFile(#Fichier_Ico)
      
      If icon = 0
            ProcedureReturn -1
      EndIf
      
      ProcedureReturn icon
EndProcedure

Global hicon, hicon_Png


OpenWindow(0, 0, 0, 600, 808, "Essai", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetWindowColor(0, #White)



;// chargement du ICO
hicon = Load_PNG_to_Ico("G:\Icones\Png\lilitux-slip-tux.ico", #False)
If hicon = -1
      MessageRequester("Erreur", "Impossible de charger l'icône", 16)
      End
EndIf
ImageGadget(0, 25, 10, 0, 0, hicon)

;// chargement du PNG
hicon_Png = Load_PNG_to_Ico("G:\Icones\Png\juanito15-tux-pompier-new-yorkais_512_512.png")
If hicon_Png = -1
      MessageRequester("Erreur", "Impossible de charger le PNG", 16)
      DestroyIcon_(hicon)
      End
EndIf
ImageGadget(1, 25, 276, 0, 0, hicon_Png)

Repeat
      
Until WaitWindowEvent() = #PB_Event_CloseWindow

DestroyIcon_(hicon)
DestroyIcon_(hicon_Png)