Animer vos Gifs avec TGIFViewer sous Lazarus
Un composant de Jérôme Delauney
Le 2018-06-23 22:45:07, par BeanzMaster, Expert confirmé
TGIFViewer 👀
Composant d'animation de GIFs pour Lazarus
Bonjour à tous,
Suite à notre discussion, je vous présente le composant TGIFViewer en version 1.0.
TGIFViewer est un composant visuel pour l'affichage d'animations au format GIF (Graphic Interchange Format) avec Free Pascal et Lazarus.
Compatibilité : Windows, Linux et MacOS
Capacités de TGIFViewer :
Voici une démonstration avec MacOS :
ℹ️ Contient également deux unités :
ℹ️ Vous pouvez télécharger GIF-ImageTestSuite pour tester avec plusieurs GIFs encodés différemment.
Installation :
Le composant TGIFViewer sera installé dans la section Beanz Extra.
Note :
L'application de démonstration GifView du dossier Demos ne nécessite pas l'installation du composant dans l'EDI pour fonctionner.
Licence : MPL
Téléchargement à partir de DVP
Que pensez-vous de ce composant ?
Quels outils graphiques souhaiteriez-vous voir développés avec Lazarus ?
Composant d'animation de GIFs pour Lazarus
Bonjour à tous,
Suite à notre discussion, je vous présente le composant TGIFViewer en version 1.0.
TGIFViewer est un composant visuel pour l'affichage d'animations au format GIF (Graphic Interchange Format) avec Free Pascal et Lazarus.
Compatibilité : Windows, Linux et MacOS
Capacités de TGIFViewer :
- Chargement depuis un stream, un fichier ou une ressource (fonctions LoadFromStream, LoadFromFile, LoadFromResource) ;
- Extraction des images brutes (**fonction DisplayRawFrame) ;
- Extraction des images pré-calculées de l'animation (fonction DisplayFrame ) ;
- Affichage avec ou sans transparence (Transparent) ;
- Gestion silencieuse de certaines données mal encodées pour permette l'affichage des images sans perturber l'utilisateur ;
- Gestion des erreurs pour les fichiers mal compressés (OnLoadError) ;
- Centrage (Center), redimensionnement (Stretch) de l'affichage ;
- Dimension du composant automatique en fonction de l'image (AutoSize) ;
- Evénement à la lecture, l'arrêt ou la mise en pause de l'animation (OnStart, OnPause, OnStop) ;
- Accès aux images et informations du GIF via la propiété Frames.Items[x].
- Traduction des messages interne via les fichiers po du français à l'anglais à l'aide du composant de Gilles Vasseur TGVTranslate légèrement modifié provenant de son tutoriel Comment internationaliser une application avec Free Pascal/Lazarus (voir demonstration gifview. Notez que vous devez copier le dossier languages dans le dossier de sortie de l'executable )
Voici une démonstration avec MacOS :
ℹ️ Contient également deux unités :
- uFastBitmap : classe pour la manipulation de bitmaps 32 bits au format RGBA ou BGRA suivant l'OS ;
- TypesHelpers : classes ajoutant des fonctions utiles au type de données (byte, integer, string, double, TDateTime...) les fonctions sont accessibles directement par la complétion du code sous Lazarus.
- GVTranslate : Classe d'aide pour traduire une application
ℹ️ Vous pouvez télécharger GIF-ImageTestSuite pour tester avec plusieurs GIFs encodés différemment.
Installation :
- Dans Lazarus, allez dans le menu "Paquet" et sélectionnez "Ouvrir un fichier de paquet (".lpk"
; - Sélectionnez gifviewer_pkg.lpk du dossier Package ;
- Cliquez sur le bouton "Compiler" ;
- Cliquez sur le bouton "Utiliser" puis "Installer".
Le composant TGIFViewer sera installé dans la section Beanz Extra.
Note :
L'application de démonstration GifView du dossier Demos ne nécessite pas l'installation du composant dans l'EDI pour fonctionner.
Licence : MPL
Téléchargement à partir de DVP
-
jurassic porkExpert éminenthello,
Félicitations pour ton composant !
Juste une suggestion :
Il serait peut-être bien d'inclure dans les fichiers de la démo GifView au moins un gif animé. Je te propose le fpclogo
En pièce jointe le logo en gif animé et aussi le lrs (pour peut être remplacer la ressource de l'autre démo GifRes).
Ami calmant, J.Ple 25/06/2018 à 6:40 -
JipétéExpert éminent séniorc't'un peu la pagaille, question "noms des choses" :
voyant que cbxStretchMode.Items peut contenir rsStretchAll ou rsStretchOnlyBigger (ou d'autres) et que je ne veux pas AutoStretchMode := smStretchAll; je me suis dit que j'allais remplacer ce smStretchAll par un smStretchOnlyBigger puisque la construction orthographique est similaire à sm/rsStretchAll, ce que j'ai fait et donc erreur de compil car smStretchOnlyBigger est inconnu, il m'a donc fallu farfouiller pour découvrir qu'il fallait utiliser smOnlyStretchBigger, totalement illogique !
Je le résume ainsi :
Code : 1
2rsStretchAll / smStretchAll rsStretchOnlyBigger / smOnlyStretchBigger
Bon, ceci étant mis en place, ça fonctionne correctement, on devrait donc voir le bout du tunnel (pas comme avec ma pompe...)
Mais d'un point de vue "rédaction", ce n'est pas tout :
Si on fait une recherche du mot OnStretchChanged on ne va jamais trouver la procédure, il lui manque un "r"
Idem avec le compo chkTansparent qui a perdu son "r".
Je te laisse corriger ces points et je retéléchargerai ensuite, histoire de continuer à être en phase.le 06/07/2018 à 18:49 -
BeanzMasterExpert confirméMise à jour :
- Amélioration de la traduction anglaise
- Amélioration du système traduction dans la démo GifView. Plus besoin de redémarrage. (modification des fichiers PO)
- Corrections des éléments mal orthographiés dans le code
Téléchargement Direct
TGIFViewer est également disponible depuis "Online Package Manager" (Gestionnaire de paquets en ligne)le 07/07/2018 à 0:25 -
BeanzMasterExpert confirméEt enfin voilà le test sous Linux :
[vidéo supprimée]
C'est quand même fou que d'être obligé de passer par TLazIntfImg sous Linux pour que la transparence soit gérée correctement.
PS : Les sources ont été mises à jour. Tout roule dans les trois mondesle 24/06/2018 à 3:58 -
BeanzMasterExpert confirméLe bug du stretch est corrigé et le github mise à jourle 24/06/2018 à 12:52
-
inforockMembre actifBonsoir,
J'espère que vous ne m'en voudrez pas de m'incruster dans vos échanges très instructifs (perso, j'apprends pas mal de choses concernant le graphisme). Je n'ai pas encore pratiqué / essayé, mais mon cahier de prise de notes se remplit
Concernant le pb de traduction rencontré par Jipété :
Le code sur le wiki utilise, pour Linux, la recherche de la valeur de la variable d'environnement LC_CTYPE via la fonction GetEnvironmentVariable. Sur mon Ubuntu 16.04 LTS, la variable locale est bien renseignée (LC_CTYPE="fr_FR.UTF-8", variable visualisable avec la commande "locale".
Je n'ai pas encore regardé plus en détail pourquoi, mais la fonctionCode : GetEnvironmentVariable('LC_CTYPE')
J'ai remplacé la variable "LC_CTYPE" par "LANG" et la fonction suivanteCode : GetEnvironmentVariable('LANG')
Dans le code du wiki, en remplaçant "LC_CTYPE" par "LANG", la fonction GetOSLanguage renvoie "fr", ce qui correspond bien aux 2 premiers caractères du contenu de la variable locale LC_CTYPE.
D'ailleurs, je ne comprends pas trop pourquoi ils ont utilisé LC_CTYPE au lieu de LANG
Désolé pour cette incursion dans vos échanges.
Bonne soirée.
Cdt
Laurentle 29/06/2018 à 19:05 -
inforockMembre actifBonsoir,
Je pense avoir trouvé une solution pour accéder aux valeurs des variables LC_xxxxx
En fait, dans l'unité clocale, il y a la définition de la fonction setlocale. Mais les constantes qui y sont liées sont incomplètes (il n'y en a que 6 de définies alors qu'en réalité il en existe 12).
J'ai donc créé ce code pour utiliser la fonction setlocale et redéfinir (enrichir) les constantes :Code : 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32unit u_setlocale; {$mode objfpc}{$H+} interface {$linklib c} uses Unix, // Pour la définition de cint initc; // Pour la définition de clib const LC_CTYPE = 0; LC_NUMERIC = 1; LC_TIME = 2; LC_COLLATE = 3; LC_MONETARY = 4; LC_MESSAGES = 5; LC_ALL = 6; LC_PAPER = 7; LC_NAME = 8; LC_ADDRESS = 9; LC_TELEPHONE = 10; LC_MEASUREMENT = 11; LC_IDENTIFICATION = 12; function setlocale(category: cint; locale: pchar): pchar; cdecl; external clib name 'setlocale'; implementation end.
Et ça m'affiche bien la valeur de la variable ! En tout cas, dans mon environnement ...
L'exemple d'utilisation de la fonction GetEnvironmentVariable est faux sur le wiki de freepascal. En effet, l'exemple utilise la variable locale LC_CTYPE or la fonction ne peut accéder (du moins dans mon environnement) qu'aux variables "globales" et non "locales". Avec cette fonction, j'arrive à afficher toutes les variables qui sont affichées via la commande linux env. Je pense d'ailleurs que c'est pour cela que sous linux, il y a la commande locale qui permet d'afficher les variables LC_xxxxxx --> ce qui implique qu'il faut utiliser une fonction spécifique pour y accéder aussi en pascal.
Toujours en recherchant sur le wiki des infos sur la fonction setlocale, dans la page traitant de i18n et des fichiers po pour les traductions, pour avoir la langue par défaut, ils utilisent GetEnvironmentVariableUTF8 avec la variable d'environnement LANG.
A moins ne pas avoir correctement recherché, la fonction setlocale n'est pas du tout documentée sur le wiki ... et entre l'absence de documentation et un exemple faux, je me suis donc basé sur la définition et l'utilisation en C.
J'ai encore squatté mais ce coup-ci, c'est avec du pascal
Bonne soirée.
Cdt
Laurentle 30/06/2018 à 19:26 -
BeanzMasterExpert confirméBon au moins on est synchro maintenant
Pour traiter ce point : Dans le FormCreate :Code : 1
2
3
4
5
6
7
8
9
10
11
12
13With GifViewer do Begin Parent := pnlView; Align := alClient; Top := 10; Left := 10; Center := True; AutoSize := true; OnLoadError := @DoOnBitmapLoadError; OnFrameChange := @DoOnFrameChange; OnStretchChanged := @DoOnStetchChanged; AutoStretchMode := smStretchAll; //------> LIGNE A MODIFIEE End;
Code : 1
2
3
4
5
6
7
8
9with cbxStretchMode.Items do begin clear; Add(rsStretchManual); // Index 0 Add(rsStretchAll); // Index 1 Add(rsStretchOnlyBigger); // Index 2 Add(rsStretchOnlySmaller); // Index 3 End; cbxStretchMode.ItemIndex := 1; // A MODIFIER SUIVANT LE PARAMETRE DANS LE ONCREATE
Changer cbxStretchMode.ItemIndex léve l'évènement OnChange mais pas OnSelectCode : 1
2
3
4
5
6
7
8
9
10
11
12Procedure TMainForm.cbxStretchModeSelect(Sender: TObject); Begin Case cbxStretchMode.ItemIndex of 0 : GifViewer.AutoStretchMode := smManual; 1 : GifViewer.AutoStretchMode := smStretchAll; 2 : GifViewer.AutoStretchMode := smOnlyStretchBigger; 3 : GifViewer.AutoStretchMode := smOnlyStretchSmaller; End; chkStretchGIF.Enabled := (GifViewer.AutoStretchMode = smManual); end;
la checkbox "Adapter" elle, est mise à jour par l'évènement OnStretchChanged du composant TGifViewerCode : 1
2
3
4Procedure TMainForm.DoOnStetchChanged(Sender: TObject; IsStretched: Boolean); Begin chkStretchGIF.Checked := IsStretched; End;
le 06/07/2018 à 14:50 -
BeanzMasterExpert confirméC'est que connaissant mon code je n'ai pas fait attention à ces petits détails
. Je vais modifié dans sens. Bien vu
Pour ce qui est de la touche r ce n'est pas la première fois, je vais lui taper dessus plus fort
C'est grâce à des personnes comme toi qui test et qui donne des retours constructifs et pertinents qu'on évolue c'est très agréable.le 06/07/2018 à 22:47 -
BeanzMasterExpert confirméSalut
J'ai trouvé le problème si tu commentes dans FormDropFiles les lignes des Labels :Code : 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30Procedure TMainForm.FormDropFiles(Sender: TObject; Const FileNames: Array Of String); var ImageFileName : String; i: integer; Begin Try GIFLoaded := False; Screen.Cursor := crHourGlass; ImageFileName := ''; ImageFileName := FileNames[0]; GifViewer.LoadFromFile(ImageFileName); //lblFileName.Caption := MiniMizeName(ImageFileName, lblFileName.Canvas ,lblFileName.ClientWidth); //lblVersion.Caption := GifViewer.Version; //lblFrameCount.Caption := IntToStr(GifViewer.FrameCount); pnlAnimationPlayer.Enabled := (GifViewer.FrameCount>1); pnlSelectFrame.Enabled := (GifViewer.FrameCount>1); edtViewFrameIndex.MaxValue := GifViewer.FrameCount-1; //edtViewFrameIndex.Value := 0; //lblCurrentFrame.Caption := '1'; //lblTotalFrame.Caption := IntToStr(GifViewer.FrameCount); GIFLoaded := True; mmoComments.Lines.Clear; for i:=0 to GifViewer.FrameCount-1 do begin mmoComments.Lines.AddStrings(GifViewer.RawFrames[i].Comment); End; Finally Screen.Cursor := crDefault; End; end
Ce comportement disparait. Pour l'éviter il faut agrandir les TPanel (1,2,3,4,5,6,7) en hauteur de quelques pixels pour que ce truc vaudou disparaisse
EDIT : Petite rectification le panel4 avait sa propriété autosize à True, ce qui provoquai ce comportement (sources mise à jour)
Ouvres un autre topics pour les bmp.
Je ne sais pas comment tu charges les BMP, mais il faut que tu fasses attention à l'ordre des composantes de couleur. Dans les fichiers BMP les couleurs sont codée au format BGR TFastBitmap sous linux est au format RGBA. Il faut donc inverser le Rouge et Bleu (procedure SwapRB) ou le faire dans ta procédure de chargement. Note le bmp que tu nous montre "FondRVB.Bmp" n'est pas mal forméc'est Lazarus qui le lit mal. Et comme je te l'ai dis jette un oeil dans BZImageFileBMP.pas que je t'ai passé. Je l'ai justement blindé de commentaires parce que j'en ai ch.... Tu y trouveras plein d'informations qui t'aideront, j'en suis sure avec ce format qui semble pourtant facile à prendre en charge. Il reste encore quelques erreurs notamment avec la compression RLE dans certain cas ou je ne gère pas les erreurs d'encodage correctement et quelques couleurs que je n'ai pas inversé (surtout les bmp os22x 8bits)
Si tu veux des BMP bizarres et hors normes à tester : https://github.com/jdelauney/BMP-ImageTestSuite
A+le 10/07/2018 à 16:49