IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Animer vos Gifs avec TGIFViewer sous Lazarus
Un composant de Jérôme Delauney

Le , par BeanzMaster

132PARTAGES

14  0 
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 :
  • 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 :
  1. Dans Lazarus, allez dans le menu "Paquet" et sélectionnez "Ouvrir un fichier de paquet (".lpk" ;
  2. Sélectionnez gifviewer_pkg.lpk du dossier Package ;
  3. Cliquez sur le bouton "Compiler" ;
  4. 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

Que pensez-vous de ce composant ?
Quels outils graphiques souhaiteriez-vous voir développés avec Lazarus ?

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de jurassic pork
Expert éminent https://www.developpez.com
Le 25/06/2018 à 6:40
hello,
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.P
2  0 
Avatar de Jipété
Expert éminent sénior https://www.developpez.com
Le 06/07/2018 à 18:49
c'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 : Sélectionner tout
1
2
rsStretchAll        / smStretchAll
rsStretchOnlyBigger / smOnlyStretchBigger
Ça saute aux yeux qu'il y a un truc faussé, là.
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 :
Citation Envoyé par BeanzMaster Voir le message
la checkbox "Adapter" elle, est mise à jour par l'évènement OnStretchChanged du composant TGifViewer
Code : Sélectionner tout
Procedure TMainForm.DoOnStetchChanged(Sender: TObject; IsStretched: Boolean);
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.
2  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 07/07/2018 à 0:25
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)
2  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 24/06/2018 à 3:58
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 mondes
1  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 24/06/2018 à 12:52
Le bug du stretch est corrigé et le github mise à jour

1  0 
Avatar de inforock
Membre actif https://www.developpez.com
Le 29/06/2018 à 19:05
Bonsoir,

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é :

Citation Envoyé par BeanzMaster Voir le message

Bizarre surtout que la fonction provient du wiki http://wiki.freepascal.org/Translati...e_syst.C3.A8me
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 fonction
Code : Sélectionner tout
GetEnvironmentVariable('LC_CTYPE')
renvoie une chaîne vide ... Le pb vient donc plus précisément de cette fonction qui ne renvoie pas le contenu de la variable locale "LC_CTYPE"

J'ai remplacé la variable "LC_CTYPE" par "LANG" et la fonction suivante
Code : Sélectionner tout
GetEnvironmentVariable('LANG')
me renvoie une chaîne contenant "fr_FR.UTF-8" qui est la même chose que la variable locale LC_CTYPE.

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

Laurent
1  0 
Avatar de inforock
Membre actif https://www.developpez.com
Le 30/06/2018 à 19:26
Bonsoir,

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 : Sélectionner tout
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
32
unit 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.
Après avoir ajouté l'unité dans les uses d'un petit programme de tests, j'appelle la fonction setlocale en indiquant la variable LC dont je veux la valeur. Exemple d'appel : setlocale(LC_CTYPE,'')

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

Laurent
1  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 06/07/2018 à 14:50
Citation Envoyé par Jipété Voir le message
D'accord, donc je suis bien en phase avec la nouvelle version (d'ailleurs on le voit à la nouvelle zone "Commentaires", et donc le problème est bien vivant :
1er lancement après compil (la combo annonce "Toutes", 1er fichier ouvert, il est agrandi :

Le drame, c'est que même en faisant cbxStretchMode.ItemIndex := 2;//1; dans FormShow, recompil, exécution, drag'n'drop du léopard et il est agrandi alors que la combo écrit bien "Les plus grandes".


Et même en déplaçant les instructions de FormShow à FormCreate ça a ce comportement bizarre...

EDIT : une solution se fait jour :
uGifViewer.pas ligne 2380 : if FAutoStretchMode <> smManual then <<< la piste !

Point d'arrêt sur cette ligne, F9, d'n'd petit fichier, souris sur FAutoStretchMode --> l'infobulle affiche SMSTRETCHALL donc le code se tamponne de la valeur de la combobox...

Et comment est-ce possible alors que le uGifViewer.Create stipule : FAutoStretchMode := smManual; ?

À cause du FormCreate ! Presque tout en bas :
Code : Sélectionner tout
1
2
    AutoStretchMode := smStretchAll;
  End;
Je m'en sors avec
Code : Sélectionner tout
1
2
    AutoStretchMode := TGifAutoStretchMode(cbxStretchMode.itemindex);//smStretchAll;
  End;
mais est-ce que c'est correct par rapport au reste ?
D'autant plus qu'il faut alors conserver l'initialisation de la combo dans le FormCreate plutôt que dans le FormShow.

Bien sûr ça contrevient à l'idée de l'autostretch mais ce truc m'importune dans la mesure où il n'est pas désactivable depuis l'IHM.
Je te laisse réfléchir à cet aspect des choses.
/EDIT

Bon au moins on est synchro maintenant

Pour traiter ce point : Dans le FormCreate :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
With 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;
Puis dans le FormShow

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
  with 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
Citation Envoyé par anapurna Voir le message
salut

le composant cbxStretchMode n'as pas de methode onchange ?
normalement c'est ici que tu devrais initialiser ta variable global
Code : Sélectionner tout
AutoStretchMode
En effet le changement se fait par l'évènement OnSelect car sinon utiliser OnChange changerai également la propriété "AutoStretchMode" ce qui provoque une erreur car au changement de celle-ci un appel à Invalidate est effectué. (si je me souviens bien)
Changer cbxStretchMode.ItemIndex léve l'évènement OnChange mais pas OnSelect

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
Procedure 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 TGifViewer

Code : Sélectionner tout
1
2
3
4
Procedure TMainForm.DoOnStetchChanged(Sender: TObject; IsStretched: Boolean);
Begin
  chkStretchGIF.Checked := IsStretched;
End;
Citation Envoyé par Jipété Voir le message

Non, sur le continent, mais oui, presque au bord de la grande Bleue et je n'en dirai pas plus, qu'après je vais me faire géolocaliser,
1  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 06/07/2018 à 22:47
Citation Envoyé par Jipété Voir le message
c'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 : Sélectionner tout
1
2
rsStretchAll        / smStretchAll
rsStretchOnlyBigger / smOnlyStretchBigger
Ça saute aux yeux qu'il y a un truc faussé, là.
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.
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.

1  0 
Avatar de BeanzMaster
Expert confirmé https://www.developpez.com
Le 10/07/2018 à 16:49
Salut
Citation Envoyé par Jipété  Voir le message
Salut,

me voilà de retour, je vois le bout du tunnel avec la pompe : après avoir changé la pompe entière et le clapet anti-retour, ça serait malheureux ! Reste un souci avec la pompe électrique...

J'ai refait ton test et chez moi ça se comporte comme déjà signalé : c'est le pnlView qui s'agrandit, qu'il y ait commentaire ou pas.

Il est là le souci (mais je ne sais pas où c'est calculé, et je n'ai pas le temps c't'aprème).

J'ai trouvé le problème si tu commentes dans FormDropFiles les lignes des Labels :

Code : Sélectionner tout
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
Procedure 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)

Citation Envoyé par Jipété  Voir le message
Tu remarqueras que sur cette animation (générée avec commentaire, si tu veux la tester) la taille de la fiche est un poil plus haute et il y a un bouton "test" qui est apparu : je voulais voir comment réagissait ton TFastBitmap avec un .bmp mal formé, et la conclusion que j'en tire est la suivante : à gauche avec un TBitmap, à droite avec ton TFastbimap (qui "rend" comme un TLazInftImage), en bas au milieu le viewer de Linux.

J'avais déjà travaillé avec ce fichier qui vient du forum Delphi, où je m'étais arraché les cheveux.

La grande question est : est-ce que je continue à polluer ce post avec ce sujet qui dérive, ou est-ce que j'en ouvre un autre, qui pourrait s'appeler "Comment travailler avec un bmp mal formé, si on ne le sait pas" -- car là, je m'en doute puisque je peux le comparer avec le rendu Linux, mais IRL ?

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+
1  0