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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Transtypage de string en Txyz [Lazarus]


Sujet :

Lazarus Pascal

  1. #21
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonjour Yves,

    Citation Envoyé par tourlourou Voir le message
    Voici une illustration de la class factory
    Tiens c'est marrant, ça, ça me fait penser à complètement autre chose,

    Enjoy :


    Et sinon, je ne te remercierai jamais assez, ton code a compilé du premier coup (juste faire attention au "frm", ) et s'est exécuté tip-top !

    Plus qu'à (essayer de) tout comprendre, et c'est là que ça va un peu coincer : je connais mes limites...

    Exemple : function QuiSuisJe: string; virtual;.


    Une function blabla: string; je vois et capte instantanément ce que ça fait, c'est du concret de chez concret, du lourd, quoi.
    Tu rajoutes "virtual;" au bout et c'est fini, je perds tous mes moyens intellectuels, je ne comprends comprends comprends pas : cette fonction ne retourne plus une bête string ? Elle retourne quoi, alors ? Une string virtuelle ? C'est quoi cette bête sournoise ?

    J'avoue humblement être largué depuis le début de la POO sur ce coup-là...

    Dans l'attente d'un petit coup de projecteur sur ce point sombre, mille millions de mercis pour ce qui précède !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #22
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    C'est pour le polymorphisme. Virtual veut dire qu'une classe dérivée peut (ce n'est pas obligatoire) surcharger la méthode (override).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    type
      TMyClass = class
        function ShowText :string; virtual;
      end;
     
      TMySubClass = class(TMyClass)
        function ShowText :string; override;
      end;
    On peut ainsi déclarer une variable de type générique TMyClass et l'instancier avec le type dérivé TMySubClass. Le ShowText appelé sera celui de TMySubClass.
    Si on omet virtual et puisque la variable est de type TMyClass, c'est celui de TMyClass qui est appelé, même si l'instance est effectivement du type TMySubClass. Le lien est rompu.

    En d'autres termes :
    sans virtual, on se base sur le type déclaré ;
    avec virtual, sur le type réel (si override).

  3. #23
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    Bien expliqué !

    Pour tes devoirs de vacances, JP : relis à l'occasion les tutos de Gilles Vasseur sur la POO...

    Et pardon à anapurna de ne pas avoir lu tous ses posts (notamment celui de 12h02), aux solutions plus élégantes (TStringList notamment) que le tableau...
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  4. #24
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Pour tes devoirs de vacances, JP : relis à l'occasion les tutos de Gilles Vasseur sur la POO...
    À l'occasion, promis,

    Citation Envoyé par tourlourou Voir le message
    Et pardon à anapurna de ne pas avoir lu tous ses posts (notamment celui de 12h02), aux solutions plus élégantes (TStringList notamment) que le tableau...
    Mais pourquoi ? Une TStringList n'est-elle pas un bête tableau de... strings ?

    Et grand merci à Andnotor pour sa lumineuse explication
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  5. #25
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    en théorie oui, le Tstringlist est une liste de string, sauf que dans leur infini sagesse il l'ont couplé avec une liste d'objet
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  6. #26
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par anapurna Voir le message
    salut

    en théorie oui, le Tstringlist est une liste de string, sauf que dans leur infinie sagesse il l'ont couplé avec une liste d'objet
    Bah, si on devait faire avec des tableaux, il suffirait d'en prendre deux, comme avec l'écuyère au cirque avec deux chevaux : un pied sur chacun et en avant pour les tours de piste !
    Au lieu de faire for i := 0 to longueur_tableau-1 do tableaustring[i] := 'du texte'; tu feras
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for i := 0 to longueur_tableau-1 do 
    begin
      tableaustring[i] := 'du texte'; // rien de changé
      tableauobjets[i] := un_objet; // juste ça en plus
    end;
    et voilà !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  7. #27
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    pour le parcourt d'un tableau
    je prefere

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     for i:= low(montab) to high(montab) do
    cela t’évite de commencer a zéro alors que le tableau est déclaré
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  8. #28
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Yep !
    Citation Envoyé par anapurna Voir le message
    pour le parcours d'un tableau
    je préfère
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     for i:= low(montab) to high(montab) do
    Mis en application pour parcourir mon tableau de filtres, c'est ok, la preuve :
    Nom : remplissage_combobox.png
Affichages : 126
Taille : 5,1 Ko

    Grande victoire sur l'adversité et les démons sournois tapis dans l'ombre et les méandres des classes virtuelles et autres abstractions totalement incompréhensibles au pauvre péquenot terre-à-terre que je suis, qu'on en juge :

    Ayant regardé attentivement le tuto n° 2 de Gilles, j'y ai trouvé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type
      TEtreVivant = class
      public
        procedure Boire; virtual; abstract; // à définir par les descendants
      end;
    sans plus d'explications (qui sont sans doute ailleurs mais j'aurais préféré les avoir sous les yeux), donc merci Andnotor pour ton post d'hier, et plus loin (à peine raccourci) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      TAnimal = class(TEtreVivant)
      strict  private
        fASoif: Boolean;
      public
        procedure Boire; override;  // OK pour abstract
      published
        property ASoif: Boolean read fASoif write fASoif;
      end;
    // OK pour abstract oui, et alors ? Voilà un autre commentaire qui n'explique rien lui non plus.

    MP pour Gilles :
    Des méthodes et propriétés sans rapport avec l'abstraction ont été ajoutées afin de montrer que les classes enfants sont libres de définir ce qu'elles souhaitent en addition aux méthodes abstraites.
    Ce § devrait être "remonté" sous le listing "unit abstractanimal;", àmha -- ça serait plus clair, je pense.

    Bon, en ce qui me concerne, je crois que le problème est là :
    Pour vous en convaincre, vous allez examiner la classe TStrings de la RTL de Free Pascal, chargée de gérer à son niveau fondamental une liste de chaînes. Ce sont en fait ses descendants comme TStringList, une des classes les plus utilisées de la RTL, qui implémenteront les méthodes à même de traiter réellement les chaînes manipulées.
    C'est un peu comme si on demandait à un chauffeur de taxi, qui doit connaître les rues de sa ville par cœur, de suivre un master en physique nucléaire sur la résistance des matériaux, juste parce que les pistons de son moteur sont en céramique.
    Je trouve tout ça bien compliqué (ou alors c'est la chaleur, déjà, de bon matin...)

    Par ailleurs, en termes purement linguistiques et de compréhension des mots au 1er degré, en lisant ça dans le post d'Yves :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type
      TAncetre = class
        class function CreateDescendant(aIndex: integer): TAncetre; // méthode de classe
    j'ai du mal à capter car pour moi CreateDescendant signifie qu'il est question de créer un descendant au type TAncetre et nom pas du type TAncetre, ce qui n'a aucun sens : je ne peux pas créer un descendant du type ascendant, je peux par contre créer un descendant à l'ascendant : mon fils descend de moi, il n'est pas un jumeau de moi.
    J'aurais peut-être un peu mieux compris si j'avais lu class function CreateDescendant(aIndex: integer): TDescendant;

    Plus loin c'est pareil !
    Je tombe sur TClasseDescendant = class of TAncetre; que je traduis par le type Descendant est du type Ancêtre.
    Le fils est le père, et le serpent se mord la queue !
    Au secours, laissez-moi sortir !


    Encore plus fort, toujours dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var
      Descendant: TAncetre;
    pour moi ce que je lis là n'a aucun sens, d'ailleurs, en regardant le type basique d'une fiche (nouvelle application et y poser un bouton), on voit bien qu'un Button1 est du type TButton, c'est logique -- les choses seraient plus simples si je pouvais lire Descendant1: TDescendant; ou Ancetre1: TAncetre; -- alors, oui, si j'avais pour les boutons
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    schmilblik: TButton;
    zorglub: TButton ;
    ça fonctionnerait aussi, tout comme avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    scrollbox: TButton;
    un_panel : TButton;
    mais faudrait être bien dérangé du bulbe pour appeler ses boutons ainsi (les miens commencent par "btn") alors désolé, mais pour moi Descendant: TAncetre ça ne passe pas, et à partir de là tout le reste s'écroule.

    Surtout quand je lis ça un peu plus bas :
    Les méthodes de classe obéissent en effet aux mêmes règles de portée et d'héritage que les méthodes ordinaires. En particulier, elles peuvent être virtuelles.
    Là, je me dis que la POO n'est vraiment pas un truc pour moi : je ne vois dans cette citation claire et limpide et sans aucune faute qu'un charabia incompréhensible, une bouillie de mots ne représentant rien, et je ne peux pas passer mon temps à jouer avec la roulette de la souris pour revoir à chaque fois ce que veut dire tel ou tel mot, mots qui se refusent à intégrer les neurones fatigués de ma cervelle bouillante...

    Tu vois, j'ai fait l'effort d'y aller voir mais je me suis retrouvé en perdition en plein brouillard...
    Bon, je ne renonce pas, je vais avancer step-by-step avec ma méthode : je change une chose ici j'exécute et je vois ce que ça donne, puis je change une autre chose là et etc.

    Et au final, en repartant de mon tableau de TFPCustomInterpolation (d'hier ou avant-hier, je ne sais plus) et ayant découvert grâce à la complétion la magie de la propriété ClassName (je crois que c'est anapurna [encore lui ! Quel garçon efficace ] qui m'a mis sur la piste), ben vous avez vu en haut l'image, avec le Combobox rempli dynamiquement à la création du tableau dans le FormCreate. Trop bien !


    Je peux recocher

    EDIT : 2 minutes pour passer de la maquette à la vraie vie, que du bonheur !
    Nom : combofull.png
Affichages : 132
Taille : 9,6 Ko

    Plus qu'à tester (et là, je sais déjà qu'il va y avoir du sport...)
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  9. #29
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type
      TEtreVivant = class
      public
        procedure Boire; virtual; abstract; // à définir par les descendants
      end;
    sans plus d'explications (qui sont sans doute ailleurs mais j'aurais préféré les avoir sous les yeux), donc merci Andnotor pour ton post d'hier, et plus loin (à peine raccourci)
    Si on repart de ceci :
    Citation Envoyé par Andnotor Voir le message
    C'est pour le polymorphisme. Virtual veut dire qu'une classe dérivée peut (ce n'est pas obligatoire) surcharger la méthode (override).
    l'ajout de abstract donnerait :
    Virtual abstract veut dire qu'une classe dérivée doit surcharger la méthode si elle veut l'utiliser puisque l'implémentation n'existe pas encore (le numéro dans la rue a déjà été attribué mais la maison n'est pas encore construite ).

    Citation Envoyé par Jipété Voir le message
    Je tombe sur TClasseDescendant = class of TAncetre; que je traduis par le type Descendant est du type Ancêtre.
    Le fils est le père, et le serpent se mord la queue !
    Ce n'est pas est le père mais est du même type que le père, il en a toutes les caractéristiques.

    Citation Envoyé par Jipété Voir le message
    Encore plus fort, toujours dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var
      Descendant: TAncetre;
    pour moi ce que je lis là n'a aucun sens
    C'est pourtant ça le polymorphisme et c'est exactement ce que j'expliquais plus haut avec TMyClass, TMySubClass (tu semblais avoir compris pourtant).

    Citation Envoyé par Jipété Voir le message
    d'ailleurs, en regardant le type basique d'une fiche (nouvelle application et y poser un bouton), on voit bien qu'un Button1 est du type TButton, c'est logique
    Bien sûr que c'est logique mais c'est au design, le type réel est connu (et immuable).

    Maintenant, définis l'événement OnClick et surprise, le paramètre Sender et de type TObject et non TButton, pourtant Sender représente le bouton. Ça ne te choque pas ça ?
    TButton (Descendant) est dérivé de TObject (Ancêtre).

    Citation Envoyé par Jipété Voir le message
    les choses seraient plus simples si je pouvais lire Descendant1: TDescendant;
    Rien ne t'interdit de le faire mais ce serait juste une lourdeur supplémentaire, une classe intermédiaire qui ne fait rien, ne sert à rien et ne devrait même pas être instanciable dans ta logique.

  10. #30
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonjour bonjour,
    Citation Envoyé par Andnotor Voir le message
    C'est pourtant ça le polymorphisme et c'est exactement ce que j'expliquais plus haut avec TMyClass, TMySubClass (tu semblais avoir compris pourtant).
    J'atteins la limite de mes compétences et capacités intellectuelles, là (même si c'est évident pour d'autres).

    Citation Envoyé par Jipété Voir le message
    Plus qu'à tester (et là, je sais déjà qu'il va y avoir du sport...)
    J'ai généré ce gif en partant d'un fichier 400x300x24 et en demandant un agrandissement de 120 %, ce qui est le but final : comparer le travail des différents filtres (16) pour savoir lequel utiliser en fonction du résultat recherché.
    Regardez particulièrement le damier ou les textes, et oubliez Lena, la compression gif ne l'avantage vraiment pas :
    Nom : 16.gif
Affichages : 98
Taille : 1,03 Mo

    Pour y arriver, je suis donc parti de mon unité dérivée de extinterpolation.pp, à laquelle j'ai rajouté, tout en haut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      TArrayOfCustomInterpolation = array of TFPCustomInterpolation;
    au milieu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      aArrayOfCustomInterpolation: TArrayOfCustomInterpolation;
     
    implementation
    ...
    et tout en bas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    initialization
      // Help SetLength :
      // In the case of a dynamical array, SetLength sets the number of elements.
      // The elements are numbered from index 0, so the count runs from 0 to Len-1.
     
      SetLength(aArrayOfCustomInterpolation, 16);
      aArrayOfCustomInterpolation[00] := TBilinearInterpolation_ei.Create;
      // 14 lignes identiques, juste le nom qui change, supprimées pour alléger le post
      aArrayOfCustomInterpolation[15] := TQuadraticInterpolation_ei.Create;
    1re question : est-ce que j'ai le droit de faire ça (créer une Array of TFPCustomInterpolation), ou est-ce que je vais dans le mur ?
    Car si j'ai bien compris le film, on peut créer des Arrays de tout et n'importe quoi, alors pourquoi pas de TFPCustomInterpolation...
    En tout cas ça fonctionne, vous avez vu le gif, j'explique un poil plus bas comment j'ai fait.
    Mais je vais aussi dans le mur, continuez à lire...


    Ensuite, dans unit1, le début de l'utilisation avec le remplissage du combobox :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i: integer;
    begin
      for i:= Low(aArrayOfCustomInterpolation) to High(aArrayOfCustomInterpolation) do
        cbbxFilters.Items.Add(aArrayOfCustomInterpolation[i].ClassName);
      // allégé pour lisibilité ici
    end;
    Quand je clique sur la flèche il est rempli (vous avez vu l'image hier),
    Nom : combofull.png
Affichages : 132
Taille : 9,6 Ko
    et quand je l'utilise il me génère bien 16 fichiers plus ou moins différents, et voilà le cœur de la procédure de resize:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        for i := 0 to cbbxFilters.Items.Count-1 do begin
          SetupBMPdestination(120); // le coeff pour agrandir
          cbbxFilters.ItemIndex:=i;
          StretchDrawWithFilter(src, dst, dst.Width, dst.Height);
          dst.SaveToFile(FileUtil.ProgramDirectory+'output/agr_120/'+cbbxFilters.Items.Strings[i]+'.bmp');
        end;
    et le cœur de la sous-procédure StretchDrawWithFilter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    memo1.Lines.Add(aArrayOfCustomInterpolation[i].ClassName); // pour vérif
    Application.ProcessMessages;
        DestCanvas.Interpolation := aArrayOfCustomInterpolation[cbbxFilters.ItemIndex]; //!\ /!\ /!\
        DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
    Contact avec le mur...
    Si je vous balance ces deux bouts de proc pour l'utilisation, c'est parce qu'il est impossible de générer en une seule passe une image agrandie suivie d'une image réduite (ou l'inverse), c'est SIGSEGV garanti !
    J'ai tout tenté dans tous les sens (d'où ce post), j'en suis arrivé à la conclusion qu'il était impossible de faire un truc aussi simple que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        // pour chaque filtre
        for i := 0 to cbbxFilters.Items.Count-1 do begin
          cbbxFilters.ItemIndex:=i;
          //   a) réduire l'image et l'enregistrer
          SetupBMPdestination(80); // définit la taille du bitmap de destination
          StretchDrawWithFilter(src, dst, dst.Width, dst.Height);
          dst.SaveToFile(FileUtil.ProgramDirectory+'output/red_080/'+cbbxFilters.Items.Strings[i]+'.bmp');
     
          //   b) agrandir l'image "   "   "   "
          SetupBMPdestination(120); // définit la taille du bitmap de destination
          StretchDrawWithFilter(src, dst, dst.Width, dst.Height);
          dst.SaveToFile(FileUtil.ProgramDirectory+'output/agr_120/'+cbbxFilters.Items.Strings[i]+'.bmp');
        end;
    J'ai même essayé de rajouter entre les deux actions,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          dst.Free;
          dst := TBitMap.Create;
    ça ne change rien, et au plantage je retrouve le curseur clignotant devant memo1.Lines...

    Encore plus fort : j'utilise un second bouton pour séparer les deux jobs (un bouton pour agrandir, un bouton pour réduire), les codes sont strictement identiques à tous les points de vue, il n'y a que la variable indiquant le % du changement de taille et le sous-dossier d'enregistrement qui sont modifiés et que croyez-vous qu'il se passe en cliquant sur le second bouton peu importe que je commence par celui qui réduit ou celui qui agrandit ? Le même SIGSEGV sur le premier filtre de la liste...
    Comme s'il n'était pas possible d'utiliser deux fois les filtres.
    Quelqu'un pour m'expliquer ça ?

    Désolé d'avoir été un peu long, mais c'est pour bien cerner la chose.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  11. #31
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Bon, ben il va essayer demain, mais il rappelle qu'il a énormément de mal avec tout ce qui est abstrait, virtuel, impalpable...
    Citation Envoyé par Jipété Voir le message
    J'atteins la limite de mes compétences et capacités intellectuelles, là (même si c'est évident pour d'autres).
    Bonjour Jipété,

    Il y a environ 2,6 millions d’années, il y a eu l’émergence des homo habilis, (La classe THomoHabilis) dont le volume du cerveau dépassait déjà les 500 cm3, et chez qui est née la pensée conceptuelle. Les homo habilis étaient déjà capables de fabriquer des outils en fonction de projets futurs.

    La classe TJiPete est une classe descendante de THomoSapiens elle-même descendante de (THomoHabilis). Vous en tant que instance Jipété, comme nous tous d'ailleurs, vous eûtes été créé et instancié à partir d'une classe descendante la classe THomoSapiens, elle même, descendante de la classe THomoHabilis (Exemple TTJiPete=Class(THomoSapiens)), vous héritez donc de toutes les capacités de la classe THomoHabilis notamment la pensée conceptuelle. Donc intrinsèquement, vous allez surement finir par y arriver et comprendre ces concepts.

    Si au contraire, vous êtes un extra terrestre, ce qui n'est pas complètement exclu, alors on ne pourra rien faire pour vous !

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  12. #32
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonsoir,
    Citation Envoyé par hmira Voir le message
    [...] vous héritez donc de toutes les capacités de la classe THomoHabilis
    C'est bien ce que je m'étais noté dans un coin, pour essayer de décortiquer tout ça :

    Hiérarchie des choses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TFPCustomInterpolation = class // voir FPCanvas lignes 165 et suivantes
    TFPBaseInterpolation   = class (TFPCustomInterpolation)
    TFPSharpInterpolation  = class (TFPCustomInterpolation) // 1 cas particulier (pourquoi ?) -- LazCanvas ligne 830
    TxxxxxxxInterpolation  = class (TFPBaseInterpolation)  xxxxxxx = nom du filtre, il y en a 13 dans extinterpolation.pp
    J'ai sans aucun doute atteint mon niveau d'incompétence (comme tout le monde ) et je l'admets, c'est pourquoi je repose ma question :
    est-ce que j'ai le droit de créer une Array of TFPCustomInterpolation ?

    Car pour moi la réponse est oui, même si je me prends le mur (c'est la faute au mur ! Il n'a qu'à pas être là ).

    Sinon, comment regrouper dans la même caisse à outils le filtre TFPSharp et tous les autres Txxxxxx ? Je ne vois pas.
    Et je ne vois pas non plus pourquoi je me prends le mur.

    Imaginons un véhicule équipé d'une boîte 3 positions : marche avant-arrêt-marche arrière. Ce qui m'arrive, c'est que partant de la position arrêt, quel que soit le sens de marche choisi, il est ensuite impossible d'en changer sans exploser la boîte.
    Truc de fou...

    Et en fait, non, c'est même plus vicieux que ça (et ça m'enfonce encore plus bas, question diagnostic) : je repars d'un de mes deux boutons (celui qui réduit, au hasard) et à la fin de la boucle sur les 16 filtres, je rajoute un nouvel accès juste sur le premier filtre (si c'est un autre c'est pareil) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        ...
        end;
        SetupBMPdestination(80);
        cbbxFilters.ItemIndex:=0; // sélection 1er filtre
        StretchDrawWithFilter(src, dst, dst.Width, dst.Height);
        dst.SaveToFile(FileUtil.ProgramDirectory+'output/red_080/'+cbbxFilters.Items.Strings[0]+'.bmp');
    Et vous avez compris, paf !, le mur ligne 5...

    Je rappelle que c'est comme ça que fonctionne le tuto (à mon adaptation de l'array près) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        // Execute the stretch draw via TFPSharpInterpolation
        //DestCanvas.Interpolation := TFPSharpInterpolation.Create;//une horreur, gardé pour mémoire [origine]
        DestCanvas.Interpolation := TMitchelInterpolation.Create; // test moi OK
        //DestCanvas.Interpolation := TQuadraticInterpolation.Create; // test moi OK
    Je rappelle aussi que DestCanvas.Interpolation := attend un TFPCustomInterpolation.Create;.

    Que faire de plus ? Sortir un tarot ? Le pendule ? Faire tourner les tables ? Je ne sais pas...

    En fait, en regardant attentivement les 4 lignes qui précèdent, et la manière dont je les utilise, je me dis que j'ai un .Create mal placé :
    je remplis la liste avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    aArrayOfCustomInterpolation[00] := TBilinearInterpolation_ei.Create;
    // et les 15 autres
    et je l'utilise avec
    DestCanvas.Interpolation := aArrayOfCustomInterpolation[cbbxFilters.ItemIndex];.

    Le gag est peut-être là alors je tente un remplissage avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    aArrayOfCustomInterpolation[00] := TBilinearInterpolation_ei;
    // et les 15 autres
    mais ça ne compile pas, allez comprendre :
    Incompatible types: got "Class Of TBilinearInterpolation_ei" expected "TFPCustomInterpolation"
    alors que plus haut on peut lire TBilinearInterpolation_ei = class (TFPBaseInterpolation) et encore plus haut TFPBaseInterpolation = class (TFPCustomInterpolation).

    Bref, pour que ça compile, il me faut bidouiller
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    aArrayOfCustomInterpolation[00] := TFPCustomInterpolation(TBilinearInterpolation_ei);
    // et les 15 autres
    Ça sent son mur...

    Bah nan, ça compile pas du tout, à cause de la proc d'utilisation.
    Le bon sens, en restant dans l'idée de ce .Create déplacé, serait de maintenant faire DestCanvas.Interpolation := aArrayOfCustomInterpolation[cbbxFilters.ItemIndex].Create; mais faut pas rêver, hein !
    Incompatible types: got "TObject" expected "TFPCustomInterpolation"
    Il me semblait pourtant avoir déclaré une array of TFPCustomInterpolation, alors bon, je ne sais pas quoi lui dire, là.
    Du coup, pour avancer (vers le mur) je commente cette ligne, et ça compile sans erreur, très bien, mais ça ne passe pas le FormCreate, qui contient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      for i:= Low(aArrayOfCustomInterpolation) to High(aArrayOfCustomInterpolation) do
        cbbxFilters.Items.Add(aArrayOfCustomInterpolation[i].ClassName);
    Le mur s'est déplacé là...

    Et je n'ai plus d'idées.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  13. #33
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    est-ce que j'ai le droit de créer une Array of TFPCustomInterpolation
    Ça semble être la bonne approche, qui loge des descendants dans un tableau d'objets héritant tous de cette classe ancestrale.

    Ceci n'explique pas ton problème de réutilisation des filtres... Dont je ne sais pas qui les utilise : une procédure que tu as écrite, ou une fonction de FPC ?

    Manque-t-il une initialisation du filtre ? Sont-ils à usage unique ? Il manque du code pour explorer le problème. Essaye de voir si un TonFiltre.Initialize améliore les choses après l'avoir assigné à un Canvas.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  14. #34
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonjour Yves,

    Citation Envoyé par tourlourou Voir le message
    Ça semble être la bonne approche, qui loge des descendants dans un tableau d'objets héritant tous de cette classe ancestrale.
    Aaaaaaaaaaaaaaaaaah, tu me rassures

    Cependant, la suite de ta réponse me laisse plus que perplexe...
    Citation Envoyé par tourlourou Voir le message
    Ceci n'explique pas ton problème de réutilisation des filtres... Dont je ne sais pas qui les utilise : une procédure que tu as écrite, ou une fonction de FPC ?
    Je reprends : il y a un tuto (lien) qui fonctionne bien avec seulement 2 procédures, une main qui choisit le fichier à traiter, l'ouvre, paramètre les bitmaps, et appelle la "travailleuse" qui va bosser avec le filtre.
    Son cœur c'est ça, ie, tout ce qui est avant et après n'est pas changé dans mon utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        // Execute the stretch draw via TFPSharpInterpolation
        DestCanvas.Interpolation := TFPSharpInterpolation.Create;
    que j'ai très vite transformé en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        // Execute the stretch draw via TFPSharpInterpolation
        // DestCanvas.Interpolation := TFPSharpInterpolation.Create; // une horreur, gardé pour mémoire [origine]
        // DestCanvas.Interpolation := TMitchelInterpolation.Create; // test moi OK -- source : FPCanvas
           DestCanvas.Interpolation := TQuadraticInterpolation.Create; // autre test moi OK -- source : extinterpolation
    et qui devient au final, avec ma collection de filtres,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        // Execute the stretch draw via TFPSharpInterpolation
        // DestCanvas.Interpolation := TFPSharpInterpolation.Create; // une horreur, gardé pour mémoire [origine]
        // DestCanvas.Interpolation := TMitchelInterpolation.Create; // test moi OK -- source : FPCanvas
        // DestCanvas.Interpolation := TQuadraticInterpolation.Create; // autre test moi OK -- source : extinterpolation
           DestCanvas.Interpolation := aArrayOfCustomInterpolation[cbbxFilters.ItemIndex];
    Cette collection contient par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    aArrayOfCustomInterpolation[x] := TFPSharpInterpolation.Create;
    aArrayOfCustomInterpolation[x] := TMitchelInterpolation.Create;
    aArrayOfCustomInterpolation[z] := TQuadraticInterpolation.Create;
    Voilà. Tout est résumé ci-dessus.

    Citation Envoyé par tourlourou Voir le message
    Manque-t-il une initialisation du filtre ? Sont-ils à usage unique ? Il manque du code pour explorer le problème. Essaye de voir si un TonFiltre.Initialize améliore les choses après l'avoir assigné à un Canvas.
    1-) TonFiltre.Initialize, la complétion ne le propose pas. Cependant, on peut trouver ça, dans fpinterpolation.inc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TFPCustomInterpolation.Initialize(aimage: TFPCustomImage; acanvas: TFPCustomCanvas);
    begin
      fimage := aimage;
      fcanvas := acanvas;
    end;
    Mais ça a l'air de concerner l'image plutôt que les "internals" du filtre.

    2-) étant entendu que le tuto n'en fait pas état, je me suis lancé dans un test à partir de la proc "main" du tuto, dans un nouveau bouton (juste la partie concernée, là) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      StretchDrawBitmapToBitmap(src, dst, dst.Width, dst.Height);  // appelle la "travailleuse", qui utilise le filtre Mitchell
      image1.Picture.Bitmap := dst;
      showmessage('après affichage1'); // image1 est bien visible
      image1.Picture.Bitmap.FreeImage;
      image1.Picture := nil;
      showmessage('après affichage2'); // image1 a bien été effacée
      StretchDrawBitmapToBitmap(src, dst, dst.Width, dst.Height); // Rappelle la "travailleuse" avec le même filtre
      image1.Picture.Bitmap := dst;    // image1 bien réaffichée, pas d'AV, tout va bien
    J'en conclus que ma collection n'est pas bonne, chose que je commence à supposer de plus en plus fort, à tel point que j'ai fait un essai (totalement négatif) hier soir dont je vous ai touché deux mots à partir de "En fait, en regardant attentivement [...]" vers le milieu du post.

    Pour bien faire, il me faudrait arriver à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        // Execute the stretch draw via TFPSharpInterpolation
        // DestCanvas.Interpolation := TFPSharpInterpolation.Create; // une horreur, gardé pour mémoire [origine]
        // DestCanvas.Interpolation := TMitchelInterpolation.Create; // test moi OK -- source : FPCanvas
        // DestCanvas.Interpolation := TQuadraticInterpolation.Create; // autre test moi OK -- source : extinterpolation
        // DestCanvas.Interpolation := aArrayOfCustomInterpolation[cbbxFilters.ItemIndex];
           DestCanvas.Interpolation := aArrayOfFilters[cbbxFilters.ItemIndex].Create;
     
    aArrayOfFilters[x] := TFPSharpInterpolation;
    aArrayOfFilters[x] := TMitchelInterpolation;
    aArrayOfFilters[z] := TQuadraticInterpolation;
    Bon, je vais travailler là-dessus...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  15. #35
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    Salut JP !

    J'ai voulu faire un test à partir du même tuto que celui que tu cites : zéro ! La pauvre Léna redimensionnée me fournit une image unicolore, ou rien !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    procedure TForm1.Button1Click(Sender: TObject);
    type
      TFPCustomInterpolationClass = class of TFPCustomInterpolation;
    var
      Filtres: array[0..2] of TFPCustomInterpolationClass;
      SourceBitmap, DestBitmap: TBitmap;
      DestWidth, DestHeight: integer;
      DestIntfImage, SourceIntfImage: TLazIntfImage;
      DestCanvas: TLazCanvas;
    begin
      Filtres[0]:=TFPSharpInterpolation; // hérite directement de TFPCustomInterpolation (lazcanvas.pas)
      Filtres[1]:=TMitchelInterpolation; // hérite de TFPBaseInterpolation, qui hérite de TFPCustomInterpolation (fpcanvas.pas)
      Filtres[2]:=TLanczosInterpolation; // idem (extinterpolation.pas)
    // Using the non-native StretchDraw from LazCanvas ; from : http://wiki.freepascal.org/Developing_with_Graphics
     
      //Prepare the source
     
      SourceBitmap:=TBitmap.Create;
      SourceBitmap.LoadFromFile('c:\tests\lena.bmp'); // 512x512
      Image1.Picture.Bitmap.Assign(SourceBitmap); // vérification bien chargée
      SourceIntfImage := TLazIntfImage.Create(0, 0);
      SourceIntfImage.LoadFromBitmap(SourceBitmap.Handle, 0);
     
      // Prepare the destination
     
      DestBitmap := TBitmap.Create;
      // if not DestBitmap.HandleAllocated then DestBitmap.PixelFormat:=pf24Bit;
      // DestBitmap.PixelFormat:=pf24Bit;
      DestIntfImage := TLazIntfImage.Create(0, 0);
      DestIntfImage.LoadFromBitmap(DestBitmap.Handle, 0);
     
      DestCanvas := TLazCanvas.Create(DestIntfImage);
     
      // Execute the stretch draw via TFPSharpInterpolation
      DestCanvas.Interpolation := Filtres[0].Create;
      DestWidth:=400;
      DestHeight:=600;
      DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
     
      // Reload the image into the TBitmap
      DestBitmap.LoadFromIntfImage(DestIntfImage);
      Image2.Picture.Bitmap.Assign(DestBitmap); // vérification bien exécuté
    {
      // 2ème redimensionnement
      DestWidth:=800;
      DestHeight:=800;
      DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
     
      // Reload the image into the TBitmap
      DestBitmap.LoadFromIntfImage(DestIntfImage);
      Image3.Picture.Bitmap.Assign(DestBitmap); // vérification bien exécuté
    }
      SourceIntfImage.Free;
      DestCanvas.Interpolation.Free;
      DestCanvas.Free;
      DestIntfImage.Free;
      SourceBitmap.Free;
      DestBitmap.Free;
    //  Filtres[0].Free;
    //  Filtres[1].Free;
    //  Filtres[2].Free;
     
    end;
    [EDIT] DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage); renvoie un DestIntfImage de 1 x 1 pixels !!! en lui demandant par exemple 400 x 600...
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  16. #36
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Salut JP !

    J'ai voulu faire un test à partir du même tuto que celui que tu cites : zéro ! La pauvre Léna redimensionnée me fournit une image unicolore, ou rien !
    T'as dû te prendre les pieds dans le tapis, à force ça épuise, ce truc. EDIT : vu ton EDIT après avoir posté tout ça. Ça confirme, /EDIT

    Je suis reparti du tuto, j'ai conservé le principe des deux procs séparées, proc "travailleuse", une seule modif, l'ajout d'un paramètre à lui passer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    procedure TForm1.StretchDrawBitmapToBitmap(SourceBitmap, DestBitmap: TBitmap; 
      DestWidth, DestHeight: integer; idx: cardinal); // idx !
    qui s'utilise ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      // Execute the stretch draw via TFPSharpInterpolation
      // nouvelle version avec idx :
      case idx of
        0: DestCanvas.Interpolation := TFPSharpInterpolation.Create; // une horreur, gardé pour mémoire [origine]
        1: DestCanvas.Interpolation := TMitchelInterpolation.Create; // OK
        2: DestCanvas.Interpolation := TLanczosInterpolation.Create;
      end;
      DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
    et dans la proc appelante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      StretchDrawBitmapToBitmap(src, dst, dst.Width, dst.Height, x); //
      image1.Picture.Bitmap := dst; 
     
      dst.Width  := src.Width  * (coeff div 2) Div 100;
      dst.Height := src.Height * (coeff div 2) Div 100;
      StretchDrawBitmapToBitmap(src, dst, dst.Width, dst.Height, x); //
      image2.Picture.Bitmap := dst;
     
      dst.Width  := src.Width  * (coeff div 4) Div 100;
      dst.Height := src.Height * (coeff div 4) Div 100;
      StretchDrawBitmapToBitmap(src, dst, dst.Width, dst.Height, x); //
      image3.Picture.Bitmap := dst;
    j'ai mis x x x car en fait, j'ai fait trois manips : 0 1 2, 0 0 0, et 2 2 2

    et voilà les résultats avec une Lena 400x300 et de haut en bas image1, 2 et 3 (2 et 3 mal alignées à gauche) :
    Nom : 3 filtres.png
Affichages : 87
Taille : 133,4 Ko Nom : 3fois_sharp.png
Affichages : 95
Taille : 132,1 Ko Nom : 3fois_lanczos.png
Affichages : 140
Taille : 132,8 Ko

    De gauche à droite : les 3 filtres, juste Sharp (épaule massacrée, textes pourris), juste Lanczos.

    En attendant, tu me donnes une super idée avec ton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      TFPCustomInterpolationClass = class of TFPCustomInterpolation;
    À suivre,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  17. #37
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    Arf, il fallait donner les dimensions au Bitmap de destination...
    Le code suivant fonctionne en utilisant le même filtre, pour successivement 2 redimensionnements de la même source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    procedure TForm1.Button1Click(Sender: TObject);
    type
      TFPCustomInterpolationClass = class of TFPCustomInterpolation;
    var
      Filtres: array[0..2] of TFPCustomInterpolationClass;
      SourceBitmap, DestBitmap: TBitmap;
      DestWidth, DestHeight: integer;
      DestIntfImage, SourceIntfImage: TLazIntfImage;
      DestCanvas: TLazCanvas;
    begin
      Filtres[0]:=TFPSharpInterpolation; // hérite directement de TFPCustomInterpolation (lazcanvas.pas)
      Filtres[1]:=TMitchelInterpolation; // hérite de TFPBaseInterpolation, qui hérite de TFPCustomInterpolation (fpcanvas.pas)
      Filtres[2]:=TLanczosInterpolation; // idem (extinterpolation.pas)
     
      // Using the non-native StretchDraw from LazCanvas ; from : http://wiki.freepascal.org/Developing_with_Graphics
      //Prepare the source
     
      SourceBitmap:=TBitmap.Create;
      SourceBitmap.LoadFromFile('c:\tests\lena.bmp'); // 512x512
      Image1.Picture.Bitmap.Assign(SourceBitmap); // vérification que l'image a bien été chargée
      SourceIntfImage := TLazIntfImage.Create(0, 0);
      SourceIntfImage.LoadFromBitmap(SourceBitmap.Handle, 0);
     
      // Prepare the destination
      DestWidth:=400;
      DestHeight:=400;
      DestBitmap := TBitmap.Create;
      DestBitmap.Width:=DestWidth;
      DestBitmap.Height:=DestHeight;
      DestIntfImage := TLazIntfImage.Create(0, 0);
      DestIntfImage.LoadFromBitmap(DestBitmap.Handle, 0);
     
      DestCanvas := TLazCanvas.Create(DestIntfImage);
     
      // Execute the stretch draw via TFPSharpInterpolation
      DestCanvas.Interpolation := Filtres[0].Create;
      DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
     
     
      // Reload the image into the TBitmap
      DestBitmap.LoadFromIntfImage(DestIntfImage);
      Image2.Picture.Bitmap.Assign(DestBitmap); // vérification bien exécuté
     
      // 2ème redimensionnement
      DestWidth:=800;
      DestHeight:=800;
      DestBitmap.Width:=DestWidth;
      DestBitmap.Height:=DestHeight;
      DestIntfImage.LoadFromBitmap(DestBitmap.Handle, 0);
      DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
     
      // Reload the image into the TBitmap
      DestBitmap.LoadFromIntfImage(DestIntfImage);
      Image3.Picture.Bitmap.Assign(DestBitmap); // vérification bien exécuté
     
      SourceIntfImage.Free;
      DestCanvas.Interpolation.Free;
      DestCanvas.Free;
      DestIntfImage.Free;
      SourceBitmap.Free;
      DestBitmap.Free;
     
    end;
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  18. #38
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Arf, il fallait donner les dimensions au Bitmap de destination...

    Bien joué,
    Citation Envoyé par tourlourou Voir le message
    Le code suivant fonctionne en utilisant le même filtre, pour successivement 2 redimensionnements de la même source :
    Vérifié, validé,

    Sinon, suite à ta piste class of, j'ai un poil modifié les noms, a priori ça le fait !
    Dans mon module :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    type // manip Yves
      TFPCustomInterpolationClass = class of TFPCustomInterpolation;
      // et ce mot-clé, "class of", je ne pouvais pas le deviner
      TArrayOfFilters = array of TFPCustomInterpolationClass;
     
    var
      aArrayOfFilters: TArrayOfFilters;
     
    implementation
     
      ...
     
    initialization
      SetLength(aArrayOfFilters, 16);
      aArrayOfFilters[00] := TBilinearInterpolation_ei;
      // 14 autres entrées similaires
      aArrayOfFilters[15] := TQuadraticInterpolation_ei;
    Dans unit1 :
    FormCreate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for i := 0 to Length(aArrayOfFilters)-1 do
        cbbxFilters.Items.Add(aArrayOfFilters[i].ClassName);
      cbbxFilters.DropDownCount := cbbxFilters.Items.Count;
    bouton 15 (j'en suis à 18 ! Ménage plus tard...), proc principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
        // a) pour chaque filtre réduire l'image et l'enregistrer
        for i := 0 to cbbxFilters.Items.Count-1 do begin
          SetupBMPdestination(80);
          cbbxFilters.ItemIndex:=i;
          StretchDrawWithFilter(src, dst, dst.Width, dst.Height);
          dst.SaveToFile(FileUtil.ProgramDirectory+'output/red_080/'+cbbxFilters.Items.Strings[i]+'.bmp');
        end;
     
        // b) pour chaque filtre agrandir l'image "   "   "   "
        for i := 0 to cbbxFilters.Items.Count-1 do begin
          SetupBMPdestination(120);
          cbbxFilters.ItemIndex:=i;
          StretchDrawWithFilter(src, dst, dst.Width, dst.Height);
          dst.SaveToFile(FileUtil.ProgramDirectory+'output/agr_120/'+cbbxFilters.Items.Strings[i]+'.bmp');
        end;
    la proc "travailleuse" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        DestCanvas.Interpolation := aArrayOfFilters[cbbxFilters.ItemIndex].Create;
        DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
    Tout baigne dans l'huile !

    Yves, un milliard de mercis pour ton test qui m'a déverrouillé et a fait sauter ce mur
    Champion !
    Merci aux autres également, pour s'évertuer à me conseiller, et à supporter mes loooooooongues proses

    Bon aprème,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  19. #39
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonjour,

    ce tout petit post (ça va vous changer ) juste pour vous informer que ce matin j'ai rajouté à mon module dérivé de extinterpolation 6 filtres abandonnés dans cette vieille unité ReSample (trouvée il y a pas mal de semaines dans le projet DoubleCmd), histoire de les comparer avec ceux issus de FreePascal.

    Enfin, comparer leurs rendus sur des images, puisque maintenant je quitte le mode debug (la tête pleine de bosses, la faute au mur, ) pour entrer dans le mode prod' et c'est là que le projet précédent, CompareBmp, va avoir toute son importance !

    En conclusion, je fais donc logguer au FormCreate dans un mémo ma liste de filtres, le plus long ayant été leur intégration dans l'unité (copier/coller, changement de variables, etc.), bref, de l'édition de texte en mode méticuleux, mais ensuite F9 et hop ! :
    Code texte : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    TBellInterpolation_rs
    TBilinearInterpolation_ei
    TBlackmanInterpolation_ei
    TBlackmanBesselInterpolation_ei
    TBlackmanSincInterpolation_ei
    TBoxInterpolation_ei
    TBoxInterpolation_rs
    TBsplineInterpolation_rs
    TCatromInterpolation_ei
    TCubicInterpolation_ei
    TGaussianInterpolation_ei
    THammingInterpolation_ei
    THanningInterpolation_ei
    THermiteInterpolation_ei
    THermiteInterpolation_rs
    TLanczosInterpolation_ei
    TLanczos3Interpolation_rs
    TMitchellInterpolation_fp
    TMitchellInterpolation_rs
    TQuadraticInterpolation_ei
    TSharpInterpolation_lc
    TTriangleInterpolation_rs

    Plus qu'à utiliser ! Et ça l'a fait, sans l'ombre d'un éternuement
    2 x 22 fichiers image à analyser, au boulot mon gars.

    Excellente journée à tous, encore un grand merci,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Transtypage de string en shortstring
    Par Aooka dans le forum Débuter
    Réponses: 9
    Dernier message: 27/10/2015, 11h03
  2. Thread ShellExecute PChar string transtypage
    Par ouiouioui dans le forum Débuter
    Réponses: 11
    Dernier message: 02/11/2008, 00h51
  3. Transtypage int => char, String => char
    Par autregalaxie dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 10/04/2007, 13h48
  4. Transtypage String en Pchar impossible
    Par madfu dans le forum Delphi
    Réponses: 6
    Dernier message: 10/07/2006, 12h39
  5. [debutant] transtypage string en int
    Par melvar dans le forum Langage
    Réponses: 3
    Dernier message: 08/03/2006, 16h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo