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

Composants FMX Delphi Discussion :

Comment rendre une image en nuance de gris (monochrome) [Windows]


Sujet :

Composants FMX Delphi

  1. #21
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 844
    Points
    24 844
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Je n'ai pas assez fouillé dans les sources pour lire comment était codé TMonochromeEffect cela dit je sais obtenir le Filtre
    Cela tombe bien ce n'est pas codé en pascal dans les sources mais via binaire de pseudo-code des API du moteur graphique DirectX HLSL ou OpenGL GLSL et donc via le GPU.

    en Théorie (je ne fais pas de FMX mais le code montre qu'un TControl peut gérer une liste de TEffect qui sont ajoutés comme des enfants)
    en ajoutant un TMonochromeEffect avec comme parent ton Control devant être grisé soit en fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      TMonochromeEffect.Create(PaintBox).Parent := PaintBox;
    Cela va griser tout le Controle cible, cela se cumule en plus

    Tout dépend si finalement tu veux faire que fichier vers fichier ou si tu prévois un affichage

    En théorie, ceci doit fonctionner avec Bitmap qui sert d'entrée et sortie à la fois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    with TMonochromeEffect.Create(nil) do
    try
      ProcessEffect(nil, Bitmap, 0);
    finally
      Free();
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  2. #22
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 927
    Points
    40 927
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    En théorie, ceci doit fonctionner avec Bitmap qui sert d'entrée et sortie à la fois.
    Théorie totalement correcte pour quelqu'un qui "ne fait pas de FMX"

    voici ma petite unité test
    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
    unit UFilter;
     
    interface
     
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
      FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects;
     
    type
      TForm1 = class(TForm)
        Image1: TImage;
        Image2: TImage;
        OpenDialog1: TOpenDialog;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.fmx}
     
    uses FMX.Filter.Effects;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var aBitmap : Tbitmap;
    begin
    if OpenDialog1.Execute then
     begin
       Image1.Bitmap.LoadFromFile(Opendialog1.FileName);
       ABitmap:=Tbitmap.CreateFromFile(Opendialog1.FileName);
       try
         with TmonochromeEffect.Create(nil) do
         try
          ProcessEffect(nil,aBitmap, 0);
        finally
          Free;
        end;
        image2.Bitmap:=ABitmap;
       finally
        aBitmap.Free;
       end;
     end;
    end;
     
    end.
    et son résultat

    Nom : Capture.PNG
Affichages : 310
Taille : 90,8 Ko
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 098
    Points
    15 098
    Par défaut
    Salut,

    on voit bien les différences de rendu de l'orange de la bouée et du bleu de la mer près des palmes.

    De mon côté, je peux vous montrer ça, il n'y a pas de dégradés dans l'image d'origine à part le bleu du ciel, ça permet de bien se rendre compte des variations du vert, du jaune (qui est un rouge + vert), et du rouge :

    Nom : chebran2.jpg
Affichages : 307
Taille : 137,7 Ko
    (image réduite de moitié, comme celle d'hier, et convertie en .jpg car l'outil du forum refuse la même image en .png, )

    Quant aux filtres, si tu as accès aux pixels, tu as accès à tout et tu peux tout faire ; voilà comment je m'y prends, avec Scanline et FreePascal/Lazarus sous Linux :
    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
    procedure TForm1.ComputeGray(i: integer);
    var
      PixelsS,PixelsD: pRGBQuad;
      hs,ws,hd,wd: integer;
      gray: byte;
      R,G,B{,D}: byte;
    begin
      dstbmp.BeginUpdate();
      for hs := 0 to HSIZE-1 do begin // de haut en bas
        hd := hs;
        PixelsS := pRGBQuad(srcbmp.RawImage.GetLineStart(hs));
        PixelsD := pRGBQuad(dstbmp.RawImage.GetLineStart(hd));
        for ws := 0 to WSIZE-1 do begin // de gauche à droite
          wd := ws;
          // prendre le pixel source,
          B := PixelsS[ws].rgbBlue;
          G := PixelsS[ws].rgbGreen;
          R := PixelsS[ws].rgbRed;
          //D := PixelsS[ws].rgbReserved; n.u.
          // le passer en niveaux de gris
          case i of
            1: gray:= round((max(max(R,G),B)+min(min(R,G),B))*0.5);
            2: gray:= round(0.21*R+0.72*G+0.07*B);
            3: gray:= round(0.30*R+0.59*G+0.11*B);
            4: gray:= round(power( ( 0.2126*power(R,2.2)+0.7152*power(G,2.2)+0.0722*power(B,2.2) ),1/2.2) );
            5: gray:= (B+G+R) div 3;
          end;
          // et l'écrire dans la destination
          PixelsD[wd]:= RGBAtoBGRA(gray,gray,gray,255);
        end; // for ws
      end; // for hs
      dstbmp.EndUpdate();
    end;
    Bon, c'est juste une maquette pour voir les changements de rendu, donc je me suis arrangé pour partir d'images carrées de 310x310, si on sort de ce schéma c'est la cata assurée,
    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

  4. #24
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 119
    Points
    3 119
    Par défaut
    Bonjour,

    voici mon application fourre-tout, faite de bric et de broc, mais qui réunit tous les filtres et traitements d'images que j'ai glanés sur le net :

    FiltreImage.zip

    J'y ai ajouté les différents filtres gris cités plus haut.

    Travail d'amateur en version D7, mais quelques morceaux peuvent peut-être servir quitte à être améliorés !

    A+
    Charly

  5. #25
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 029
    Points : 40 927
    Points
    40 927
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    difficile de faire un choix. Du coup j'ai fait un contrôle temps

    Nom : Capture.PNG
Affichages : 299
Taille : 237,9 Ko

    Dans mon projet, où la qualité prime moins que la vitesse, la méthode sur la moyenne remporte la palme
    quoique, l'effet, totalement OS indépendant (faut-il le souligner ?), et dès un second appel gagne la partie (passe à 8 pour un nouveau chargement de l'image)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 098
    Points
    15 098
    Par défaut
    Yep !
    Citation Envoyé par SergioMaster Voir le message
    difficile de faire un choix.
    Normal, ton image en (peu de) couleurs se prête mal à des comparaisons. Regarde avec des ballons :

    Nom : joyeux-anniv.png
Affichages : 281
Taille : 140,7 Ko
    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
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 679
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 082
    Points
    13 082
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    cela étant, je me fais incendier par un internaute qui m'écrit qu'il ne faut pas utiliser HSL
    Et je serais assez de son avis.

    Pourquoi convertir en HSL puisque le gris peut se calculer sur la base des trois composantes ?
    Pourquoi travailler en 24 bits puisque tu veux une sortie en niveau de gris 8 bits ? Crée un bitmap 8 bits simplement.


    Après si c'est vraiment de la vitesse que tu cherches, il ne faut faire appel qu'une seule fois à Scanline (très gourmand en temps de traitement) et ensuite uniquement indexer le pointeur.

    En VCL ça donne :
    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
    function BmpToGrayscale(aBmp :TBitmap) :TBitmap;
    var
      GrayPal :TMaxLogPalette;
    begin
      aBmp.PixelFormat := pf24bit;
     
      GrayPal.palVersion    := $0300;
      GrayPal.palNumEntries := 256;
     
      for var i := 0 to 255 do
        with GrayPal.palPalEntry[i] do
        begin
          peRed   := i;
          peGreen := i;
          peBlue  := i;
          peFlags := 0;
        end;
     
      Result             := TBitmap.Create;
      Result.PixelFormat := pf8Bit;
      Result.Palette     := CreatePalette(@GrayPal);
      Result.SetSize(aBmp.Width, aBmp.Height);
     
      var Source :PRGBTriple := aBmp.ScanLine[aBmp.Height -1];
      var Dest   :PByte      := Result.ScanLine[Result.Height -1];
     
      var AlignSource := BytesPerScanline(aBmp.Width, 24, 32) -(aBmp.Width *3);
      var AlignDest   := BytesPerScanline(Result.Width, 8, 32) -Result.Width;
     
      for var y := 0 to aBmp.Height -1 do
      begin
        for var x := 0 to aBmp.Width -1 do
        begin
          Dest^ := Round(0.299 *Source.rgbtRed +0.587 *Source.rgbtGreen +0.114 *Source.rgbtBlue);
          inc(Source);
          inc(Dest);
        end;
     
        inc(PByte(Source), AlignSource);
        inc(Dest, AlignDest);
      end;
    end;

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 12/12/2014, 21h15
  2. Comment convertir une image RGB en niveaux de gris ?
    Par Imène_23 dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 07/08/2011, 14h50
  3. [HTML] Comment rendre une image cliquable?
    Par Nixar dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 11/03/2008, 09h58
  4. Comment rendre une partie d image noire?
    Par nouha_79 dans le forum Images
    Réponses: 1
    Dernier message: 13/11/2007, 16h39
  5. Comment rendre une image vidéo nette ?
    Par Le Débutant dans le forum Vidéo
    Réponses: 2
    Dernier message: 14/11/2006, 12h00

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