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

Delphi Discussion :

Tentative de charger / utiliser une image monochrome 16 bit de gris dans Delphi


Sujet :

Delphi

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut Tentative de charger / utiliser une image monochrome 16 bit de gris dans Delphi
    Bonjour,
    dan un nouveau freeware, je cherche à charger une image monochrome PNG 16 bit de gris, obtenue par capture et registration du Soleil en H-Alpha pour effectuer des traitements (masques, gamma, etc...) en 16 bit.

    Malgré mes nombreuses tentatives en utilisant Graphics32 et l'aide de l'IA je n'y arrive pas car arrive toujours une erreur du style
    "Erreur lors du chargement de l'image : Violation d'accès à l'adresse 00AC76F6 dans le module 'SunImageProcessor.exe'. Lecture de l'adresse 00000000"

    Les images existent, sont présentes dans le chemin, je peux les charger dans certains logiciels d'astronomie et elle sont bien en tons de gris 16 bit (0, 0..65000, 0) et graphics32 est fonctionnel (testé par le programme).

    je joins une toute petite image pour test en 16 bit (56 Ko).

    Ci-dessous la procedure qui échoue instantanément à la tentative de chargement de l'image, sans autres messages préalables à l'erreur ...
    LoadedBitmap.LoadFromFile(OpenDialogImage.FileName); // Charger l'image sélectionnée
    debug:
    Sortie du Thread : ID du thread : 8216. Processus SunlmageProcessorexe (5343)
    Exception 'first chance‘ à S778FB282. Classe d'exception EAccessViolation avec un message ‘Violation d'accès à l'adresse 00AC76F6 dans le module 'SunlmageProcessor.exe'. Lecture de l'adresse 00000000‘. Processus SunImageProcessor.exe (5340)

    Ce serai super si le problème probablement complexe (travail en 16 bit) pouvait être résolu par l'un de vous car ce programme envisagé ouvrirai de nouvelles perspectives aux astronautes amateurs étudiant le Soleil !
    Plus d'infos, n'hésitez pas ! Merci d'avance!

    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
    procedure TSolarImageProcessorForm.LoadImage(const FileName: string);
    var
      PNG: TPngImage;
      Bitmap32: TBitmap32;
      x, y: Integer;
      GrayValue: Word;
    begin
      // Vérification de l'existence du fichier
      if not FileExists(FileName) then
      begin
        ShowMessage('Erreur : Fichier introuvable à ' + FileName);
        Exit;
      end;
     
      PNG := TPngImage.Create;
      Bitmap32 := TBitmap32.Create;
      try
        // Chargement du fichier PNG
        ShowMessage('Chargement du fichier PNG');
        Application.ProcessMessages;
        PNG.LoadFromFile(FileName);
     
        // Initialisation de Bitmap32 aux dimensions de l'image
        Bitmap32.SetSize(PNG.Width, PNG.Height);
     
        // Copie des pixels 16 bits dans Bitmap32
        ShowMessage('Copie des pixels 16 bits dans Bitmap32');
        Application.ProcessMessages;
        for y := 0 to PNG.Height - 1 do
        begin
          for x := 0 to PNG.Width - 1 do
          begin
            // Exemple de récupération de la valeur 16 bits (tonalités de gris)
            // Assurez-vous que `Pixels[x, y]` retourne bien un mot 16 bits
            GrayValue := (PNG.Pixels[x, y] and $FFFF);
     
            // Stockage direct dans Bitmap32 avec les valeurs 16 bits intactes
            Bitmap32.Pixel[x, y] := GR32.Color32(GrayValue and $FFFF, GrayValue and $FFFF, GrayValue and $FFFF, 255);
          end;
        end;
     
        // Affichage de l'image dans le composant ImageDisplay
        ShowMessage('Affectation à ImageDisplay');
        Application.ProcessMessages;
        ImageDisplay.Picture.Bitmap.Assign(Bitmap32);
        ShowMessage('Image chargée et affichée avec succès.');
        Application.ProcessMessages;
     
      finally
        // Libération des ressources
        Bitmap32.Free;
        PNG.Free;
      end;
    end;
    Images attachées Images attachées  

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2006
    Messages : 696
    Billets dans le blog
    2
    Par défaut
    Bonsoir,
    Quelle version de Delphi utilisez vous et êtes vous en VCL ou Firemonkey (FMX) ?
    Par curiosité, est ce une photo prise avec un Sol'Ex ou une Lunt ?
    Mon site - Mes tutoriels - GitHub - Youtube - N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  3. #3
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Citation Envoyé par gbegreg Voir le message
    Bonsoir,
    Quelle version de Delphi utilisez vous et êtes vous en VCL ou Firemonkey (FMX) ?
    Par curiosité, est ce une photo prise avec un Sol'Ex ou une Lunt ?
    Bonsoir,
    J'utilise la version community d'Embarcadero (22.0) et c'est une appli VCL.
    Pour la photo, elle est très réduite ici mais d'origine faite avec du matos haut de gamme !
    si effectivement curieux des détails voir explications youtu.be/uhpPCh17Og0?si=N0iTvm7gBlvQwmV1

    cdlt,
    Sylvain

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 785
    Billets dans le blog
    65
    Par défaut
    Bonjour,
    Même s'il s'agit de FMX j'avais tenté une exploration des nuances de gris https://www.developpez.net/forums/d2...is-monochrome/
    La plupart des codes sont aussi valables pour VCL sauf la partie utilisation d'effets.

    N.B. Enlevez les application.processmessages qui me semblent inutiles

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 177
    Par défaut
    Si l'exception est dans TPNGImage.LoadFromFile cela va être complexe à débugguer sur une "community" où tu ne disposes pas les sources

    Tu nous montre une exception avec OpenDialogImage LoadFromFile que l'on n'a pas dans le code fourni, ce n'est pas clair de savoir d'où vient l'exception avec les éléments fournis
    en plus clairement l'exception est sur un objet à nil
    Soit LoadedBitmap soit OpenDialogImage, et une lecture rapide du code LoadFromFile cela semble peu problable, tout semble gérer par des exceptions dédiées EPNG...

    Surtout que l'image se charge parfaitement dans un simple TImage de Delphi 10 (17.0)
    Même si je n'ai aucune idée comment est traduit le Gris 16bits en VCL

    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
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Image1: TImage;
        procedure Button1Click(Sender: TObject);
      private
        procedure LoadImage(const FileName: string);
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    uses Vcl.Imaging.pngimage;
     
    {$R *.dfm}
     
    procedure TForm1.LoadImage(const FileName: string);
    var
      PNG: TPngImage;
    begin
      // Vérification de l'existence du fichier
      if not FileExists(FileName) then
      begin
        ShowMessage('Erreur : Fichier introuvable à ' + FileName);
        Exit;
      end;
     
      PNG := TPngImage.Create;
      try
        PNG.LoadFromFile(FileName);
        Image1.Width := PNG.Width;
        Image1.Height := PNG.Height;
        Image1.Picture.Bitmap.Assign(PNG);
     
      finally
        // Libération des ressources
        PNG.Free;
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      LoadImage('Image16BSMALL.png');
    end;
     
    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

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Bonjour et un grand merci d'essayer de m'aider !
    Je sais que c'est très compliqué !!

    De ce que j'ai compris du problème ... Les composants habituels dans Delphi n'ont effectivement aucun problème à ouvrir mon image en niveaux de gris 16 bit !
    Le problème c'est que toute valeur au dessus de 2^8 = 256 va être tronquée (peut être en utilisant une commande modulo 255 ai je lu).
    Dans certains programmes de video commerciaux (Sony Vega), à l'ouverture d'un de mes fichiers AVI écrit en 16 bit lors de la capture des images de la camera (qui sont réellement en 12b mais modifier de façon interne en 16b), chaque frame montre non pas une mais 4 repetitions de l'image ce qui s'explique par une mauvaise gestion 16b par le logiciel car effectivement 1000 / 255 = 4 !

    Ce que je tente ici c'est d'ouvrir l'image 16b sans que les valeurs ne soient tronquées (restent sur 2 bytes) et que je puisse faire des traitements en 16b comme le font des programmes d'astronomie bien connus comme RegiStax6. Registax6 ouvre l'image et montre en promenant la souris dessus des valeurs 0 .. 65,535 !
    Est ce possible en utilisant graphics32 ?

    Note : des changements du code ont été effectués pour essayer d'avancer ...

    Voici les nouvelles procedures qui ne provoquent aucun problème à la compilation mais donnent l'erreur qui suis au tout début du chargement de l'image 16b selectionnée (toutes les images 16b, ce n'est pas du à cette image). 'Debut s'affiche et de suite l'erreur (non fatale).

    [Window Title]
    Sunimageprocessor

    [Content]
    Erreur lors du chargement de l'image : Violation d'accès à l'adresse 009E76F6 dans le module 'SunImageProcessor.exe'. Lecture de l'adresse 00000000
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    procedure TSolarImageProcessorForm.LoadImage(const FileName: string);
    var
      PngImage: TPngImage;
      Bitmap32: TBitmap32;
      PixelData: TPixel16Array; // Array to store the 16-bit pixel values
      x, y: Integer;
      Scanline16: PWordArray; // For accessing 16-bit grayscale data
      PixelValue: Word;
    begin
      ShowMessage('Début du chargement de l''image PNG 16 bits');
      Application.ProcessMessages;
     
      // Check if the file exists
      if not FileExists(FileName) then
      begin
        ShowMessage('Erreur : Fichier introuvable.');
        Exit;
      end;
     
      PngImage := TPngImage.Create;
      Bitmap32 := TBitmap32.Create;
      try
        // Load the PNG file
        PngImage.LoadFromFile(FileName);
     
        ShowMessage('Fichier PNG chargé avec succès');
        Application.ProcessMessages;
     
        // Verify the PNG format
        if (PngImage.Header.BitDepth <> 16) or (PngImage.Header.ColorType <> COLOR_GRAYSCALE) then
        begin
          ShowMessage('Erreur : Le fichier PNG n''est pas au format 16 bits en niveaux de gris.');
          Exit;
        end;
     
        // Initialize Bitmap32 and the 2D PixelData array
        Bitmap32.SetSize(PngImage.Width, PngImage.Height);
        Bitmap32.Clear(clBlack32);
     
        SetLength(PixelData, PngImage.Height, PngImage.Width); // Allocate the 2D array
     
        // Process each pixel and store values in PixelData
        for y := 0 to PngImage.Height - 1 do
        begin
          Scanline16 := PngImage.Scanline[y]; // Get the 16-bit grayscale scanline
          for x := 0 to PngImage.Width - 1 do
          begin
            // Extract the 16-bit pixel value
            PixelValue := Scanline16^[x];
     
            // Store the raw 16-bit value in the array
            PixelData[y][x] := PixelValue;
     
            // Store the value in Bitmap32 for visualization (optional)
            Bitmap32.Pixel[x, y] := GR32.Color32(
              PixelValue shr 8, // Use high byte for grayscale display
              PixelValue shr 8,
              PixelValue shr 8,
              255); // Fully opaque
          end;
        end;
     
        ShowMessage('Image PNG 16 bits chargée avec succès');
        Application.ProcessMessages;
     
        // Optional: Display the image in a TImage component
        ImageDisplay.Picture.Bitmap.Assign(Bitmap32);
     
        // The PixelData array now holds the full 16-bit grayscale data for further processing.
     
      finally
        PngImage.Free;
        Bitmap32.Free;
      end;
    end;
     
     
    procedure TSolarImageProcessorForm.ButtonLoadImageClick(Sender: TObject);
    begin
      if OpenDialogImage.Execute then
      begin
        try
         ShowMessage('Debut');
         Application.ProcessMessages;
          LoadedBitmap.LoadFromFile(OpenDialogImage.FileName); // Charger l'image sélectionnée
          ShowMessage('après loadedbitmap');
         Application.ProcessMessages;
          ImageDisplay.Picture.Bitmap.Assign(LoadedBitmap); // Afficher l'image
          ShowMessage('après Display');
         Application.ProcessMessages;
        except
          on E: Exception do
            ShowMessage('Erreur lors du chargement de l''image : ' + E.Message);
        end;
      end;
    end;
    Déclarations privées

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    private
        { Déclarations privées }
        LoadedBitmap: TBitmap;        // Image chargée
        SelectionMask: TBitmap;       // Masque pour la sélection
        Threshold: Integer;           // Valeur de seuil actuelle
        type
           TPixel16Array = array of array of Word; // Define a dynamic 2D array for 16-bit pixels
        procedure LoadImage(const FileName: string);
        etc ...
    Encore merci !!!
    Sylvain

  7. #7
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    En passant ...
    Ce soir j'ai reussi une méthode de contournement provisoire :
    Charger le byte fort dans une image et le faible dans une autre ...
    C'est pas l'ideal mais en attendant un progrès car on peut déjà envisager des conbinaisons de ces deux images, disque par dessus l'image des protus ...
    Ca donne ceci en copie d'écran (on voit bien le disque à gauche et les protubérances autour à droite):

    Nom : Fort&Faible.jpg
Affichages : 284
Taille : 498,6 Ko

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 992
    Par défaut
    Citation Envoyé par sweiller Voir le message
    ouvre l'image et montre en promenant la souris dessus des valeurs 0 .. 65,535 !
    Et pourquoi faire une conversion en bitmap pour ça ?

    Premièrement le bitmap sera limité en taille et si tes images sont en haute résolution ça risque de coincer. Et deuxièmement le png offre déjà la possibilité de lire un pixel en 16 bits, donc pourquoi ne pas s'en contenter ? Il n'est en tout cas pas logique de vouloir le récupérer dans un bitmap 32 bits.

    La lecture du png dans ton code est aussi incorrect. Pour un png 16 bits, les 8 bits de poids faible sont lus par Scanline et les 8 de poids fort par ExtraScanline.

    Un exemple, (après avoir converti ton image en monochrome).

    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
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Png :TPngImage;
      Bmp :TBitmap;
      pBmp :PWord;
      pPngLow :pByte;
      pPngHigh :pByte;
    begin
      Png := TPngImage.Create;
      try
        Png.LoadFromFile('D:\Delphi\Test\Image16BSMALL2.png');
     
        Bmp := TBitmap.Create(Png.Width, Png.Height);
        try
          Bmp.PixelFormat := pf16bit;
     
          for var Y := 0 to Png.Height -1 do
          begin
            pBmp := Bmp.ScanLine[Y];
            pPngLow := Png.ScanLine[Y];
            pPngHigh := Png.ExtraScanLine[Y];
     
            for var X := 0 to Png.Width -1 do
            begin
              pBmp^ := MakeWord(pPngLow^, pPngHigh^);
              inc(pBmp);
              inc(pPngLow);
              inc(pPngHigh);
            end;
          end;
     
          Bmp.SaveToFile('D:\Delphi\Test\Image16BSMALL.bmp');
        finally
          Bmp.Free;
        end;
      finally
        Png.Free;
      end;
    end;
    L'image résultante est couleur puisqu'un Bitmap 16 bits l'est (rouge:5bits, vert:6bits, bleu:5bits).

    Nom : Image16BSMALL.jpg
Affichages : 280
Taille : 69,7 Ko

    Et donc au survol d'un TImage et après correction des coordonnées en fonction du zoom, par une simple fonction ou par un assistant de classe comme ici :
    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
    type
      TPngImageHelper = class helper for TPngImage
      public
        function GetPixelValue(X, Y :integer) :word;
      end;
     
    implementation
     
    { TPngImageHelper }
     
    function TPngImageHelper.GetPixelValue(X, Y: integer): word;
    begin
      if Header.BitDepth <> 16 then
        Raise Exception.Create('Wrong bit depth');
     
      if Header.ColorType <> COLOR_GRAYSCALE then
        Raise Exception.Create('Not grayscale');
     
      if (x < 0) or (X >= Width) or (Y < 0) or (Y >= Height) then
        Raise Exception.Create('Out of bounds');
     
      var Low  :PByte := ScanLine[Y];
      var High :PByte := ExtraScanLine[Y];
     
      inc(Low, X);
      inc(High, X);
     
      Result := MakeWord(Low^, High^);
    end;
     
    end.

  9. #9
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Et pourquoi faire une conversion en bitmap pour ça ?

    Premièrement le bitmap sera limité en taille et si tes images sont en haute résolution ça risque de coincer. Et deuxièmement le png offre déjà la possibilité de lire un pixel en 16 bits, donc pourquoi ne pas s'en contenter ? Il n'est en tout cas pas logique de vouloir le récupérer dans un bitmap 32 bits.
    Merci !
    Je m'excuse de la confusion ... J'ai compris pourquoi !
    En astronomie quand on parle d'une image 16 bit c'est une image monochrome avec 16 bit pour chaque canal ... 48 bit au total !
    Pour les images '16 bits' monochrome la decomposition du flux est la suivant (pixel(n,n,n) avec n de 0 .. 65535.
    Un peu d'histoire me semble utile ... Les premières cameras 'astro' des amateurs étaient, début années 2000, des webcams CCD modifiées au format RGB 8,8,8 bit avec lecture de 4 photosensors 1xR, 2xG,1XB (matrice de bayer) pour donner un pixel final, donc de faible résolution (~ au final 1/4 du capteur).
    Par la suite de nombreuses cameras (appelées M ou 'mono') sont apparues ... d'abord en 8bit sans matrice de bayer, puis en 10, 12, 14 et 16*** bits par canal. La dynamique et la résolution sont bien meilleures comparées au webcams. Par souci de simplification et de standardisation toutes ces cameras sortent leur flux en 16 bit sur 1 canal, les deux autres étant toujours 0 !
    *** celle ci sont rares car restent extremement couteuses en grand format !

    Pour ma part j'ai donc deux cameras monochrome HR, une en 12 et une en 14 bit de dynamique. Les écrans ne sont bien sûr qu'en RGB 24 bit mais tous les calculs sur l'image (Luminosité, contraste, gamma, convolution, math, eventuellement sur une sélection ...) se font sur une profondeur bien plus grande (10 ou 16 bit). Ainsi on peut mettre en valeur un très grand nombre de niveaux (par exemple des protubérances (luminosité ~ 1 .. 20)au coeur des eruption [flares] dans les 65500) avant de re-condenser au final la dynamique en seulement 24 bits pour l'affichage. Dans la realité, comme on veut une image en tons de gris on passe à (n,n,n) avec n = 0 .. 255. D'ailleurs ces images grises sont souvent traduites en couleurs ... Pour le Soleil colorisées avec une palette ad hoc et pour le ciel profond (comme les photos de Hubble) par combinaisons de trois images monochromes prises chacune avec un filtre laissant passer une longueur d'onde différente R, G, B, IR ou avec très faible bande passante (typiquement quelques nm) UV, Halpha, Soufre, Sodium, etc ...

    Donc mon problème est de réussir à avoir en interne des 'pixels' en 48 bit à la lecture des images formatés en 48 bit, pour les afficher (utilisation du pixel fort) et les retravailler dans un buffer de haute dynamique avant conversion 24 bit pour l'affichage !

    J'espère avoir été clair

    cdlt

  10. #10
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 177
    Par défaut
    Tu ne pourras jamais utiliser des formats VCL classique (ceux de Windows d'ailleurs) pour travailler une profondeur à 48 bits, tu dois forcément conserver une valeur brute dans un tableau de record triple Word ou utiliser le format PixelFormat48bppRGB (ça faudrait le faire directement en GDI+ sans la RTL)
    Pense que la VCL est très dépendante de Windows soit BITMAPINFOHEADER.biBitCount prévu pour 1, 4 ou 8

    Depuis le début, tous les codes fournis nous montre une manipulation d'un seul canal 16 bits ... et finalement cela devient du 48bits
    L'image que tu as fourni ne doit pas être la même que tu utilises, elle est COLOR_RGB avec effectivement 3 fois 16 bits
    Et même si on lit le code de TPNGImage, le COLOR_GRAYSCALE 16 bit et converti en 8Bits ... d'ailleurs, je me demande ce qu'apporte un image COLOR_RGB 48 (n, n, n) vs COLOR_GRAYSCALE 16 (n) avec n identique sur tous les canaux ?
    c'est pas un format ultra encombrant pour aucun gain de précision ?

    il sera peut-être nécessaire d'utiliser une autre lib pour charger ton PNG 48Bits si l'approche proposé Andnotor ExtraScanline n'est pas adapté à tes besoins
    D'ailleurs, tu peux du coup reconstituer un array of triple word avec Scanline + ExtraScanline >> 8.

    Il y a une anomalie sur ton TPixel16Array en array of word qui devrait être array of array[0..2] of Word ou array of record G1, G2, G3: Word end; si tu veux travailler en 48bits !
    Si ton code fonctionne, c'est particulièrement étrange, comme si tu ne récupérais qu'un seul canal sur les trois.
    Tu devrais déjà creuser au niveau du TPNGImage ScanLine pour récupérer du 16x3 et non juste du 16bits (oppose justement COLOR_RGB 48 vs COLOR_GRAYSCALE 16)


    Pour l'affichage, utilise le PNG Tronqué par défaut puisque tu pourras développer effectivement un affichage secondaire capable de donner la possibilité de montrer plus de "couleur" en utilisant d'autres algorithme de conversion
    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

  11. #11
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 177
    Par défaut
    Nom : Capture d'écran 2024-11-21 163712.png
Affichages : 363
Taille : 141,8 Ko

    Comme je l'évoquais, l'image que l'on reçu sur le forum est une COLOR_RGB 16 bits par canal
    Donc au final, c'est deux images 24Bits comme expliqué par AndNotOr

    On voit nettement que la VCL affiche la version 8Bits (Low)

    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
    procedure TForm1.LoadImage(const FileName: string);
    type
      TRGB24Array = array of TRGBTriple;
    var
      PNG: TPngImage;
      BLow, BHigh: TBitmap;
      Y: Integer;
      SLLow, SLHigh: TRGB24Array;
    begin
      // Vérification de l'existence du fichier
      if not FileExists(FileName) then
      begin
        ShowMessage('Erreur : Fichier introuvable à ' + FileName);
        Exit;
      end;
     
      PNG := TPngImage.Create;
      try
        PNG.LoadFromFile(FileName);
        Image1.Width := PNG.Width;
        Image1.Height := PNG.Height;
        Image1.Picture.Bitmap.Assign(PNG);
     
        if (PNG.Header.BitDepth = 16) and (PNG.Header.ColorType = COLOR_RGB) then
        begin
          BLow := TBitmap.Create();
          BLow.Width := PNG.Width;
          BLow.Height := PNG.Height;
          BLow.PixelFormat := pf24bit;
          try
            BHigh := TBitmap.Create();
            BHigh.Width := PNG.Width;
            BHigh.Height := PNG.Height;
            BHigh.PixelFormat := pf24bit;
            try
              //SetLength(SLLow, PNG.Width);
              //SetLength(SLHigh, PNG.Width);
              for Y := 0 to PNG.Height - 1 do
              begin
                //Move(PNG.Scanline[Y]^, SLLow[0], PNG.Width * 3);
                //Move(PNG.ExtraScanline[Y]^, SLHigh[0], PNG.Width * 3);
     
                Move(PNG.Scanline[Y]^, BLow.ScanLine[Y]^, PNG.Width * 3);
                Move(PNG.ExtraScanline[Y]^, BHigh.ScanLine[Y]^, PNG.Width * 3);
              end;
     
              Image2.Picture.Bitmap.Assign(BLow);
              Image3.Picture.Bitmap.Assign(BHigh);
            finally
              BHigh.Free;
            end;
          finally
            BLow.Free;
          end;
     
        end;
     
      finally
        // Libération des ressources
        PNG.Free;
      end;
    end;
    Curieusement, on dirait que c'est un négatif, cela doit avoir un sens mais comment exploiter le byte de poids fort par rapport au byte de poids faible, pas la moindre idée, je ne connais pas le format PNG RVB 16 pour le comprendre.
    Ce n'est pas un hazard mais chaque pixel vérifie l'assertion Scanline = 255 - ExtraScanline, surement que le négatif permet de mieux analysé les couleurs proche du noir (le fond étant noir empêche de lire )

    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
    procedure TForm1.btnAverageClick(Sender: TObject);
    var
      BLow, BHigh, BAvgW, BAvgB: TBitmap;
      Y, X: Integer;
      SLLow, SLHigh, SLAvgW, SLAvgB: PRGBTriple;
      C: Word;
    begin
      BLow := Image2.Picture.Bitmap;
      BHigh := Image3.Picture.Bitmap;
      BAvgW := Image4.Picture.Bitmap;
      BAvgW.Width := BLow.Width;
      BAvgW.Height := BLow.Height;
      BAvgW.PixelFormat := pf24bit;
      BAvgB := Image5.Picture.Bitmap;
      BAvgB.Width := BLow.Width;
      BAvgB.Height := BLow.Height;
      BAvgB.PixelFormat := pf24bit;
     
      for Y := 0 to BLow.Height - 1 do
      begin
        SLLow := BLow.ScanLine[Y];
        SLHigh := BHigh.ScanLine[Y];
        SLAvgW := BAvgW.ScanLine[Y];
        SLAvgB := BAvgB.ScanLine[Y];
     
        for X := 0 to BLow.Width - 1 do
        begin
          SLAvgW^.rgbtBlue := SLLow^.rgbtBlue div 2 + (255 - SLHigh^.rgbtBlue) div 2;
          SLAvgW^.rgbtRed := SLAvgW^.rgbtBlue;
          SLAvgW^.rgbtGreen := SLAvgW^.rgbtBlue;
     
          if SLLow^.rgbtBlue = 255 - SLHigh^.rgbtBlue then
          begin
            SLAvgB^.rgbtBlue := 0;
            SLAvgB^.rgbtRed := 0;
            SLAvgB^.rgbtGreen := 255;
          end
          else
          begin
            SLAvgB^.rgbtBlue := 0;
            SLAvgB^.rgbtRed := 0;
            SLAvgB^.rgbtGreen := 0;
          end;
     
          Inc(SLLow);
          Inc(SLHigh);
          Inc(SLAvgW);
          Inc(SLAvgB);
        end;
     
      end;
    end;
    Nom : Capture d'écran 2024-11-21 174210.png
Affichages : 358
Taille : 58,2 Ko
    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

  12. #12
    Membre chevronné Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    1 234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chambord
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 234
    Par défaut
    La lib BGRABitmap, gère dés profondeur de couleurs supérieur à 8 bits, j’y ai une version 16 bits, il me semble même qu’elle propose mais des valeurs plus importante.

    Même si BGRABitmap est développé pour Lazarus, il existe une version Delphi.

  13. #13
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Bonjour à tous,

    Merci pour les explications, les idées et les conseils précieux !

    Je vais revoir tout cela à tête reposée un peu plus tard (je reviendrais ici si progrès) ...

    Pour le moment, faute de mieux je cherche à terminer (c'est motivant de progresser en codage de toutes façons) avec une solution à deux images ImageHigh et ImageLow.
    Le résultat est scientifiquement intéressant (car toute l'information est là, même la plus faible et en gardant un fond bien sombre par rapport à faire un gamma sur l'extérieur du cercle) même si j'ai à régler des problèmes de bords et faire quelques traitements locaux pour gérer les zones d'éruptions.
    Voici des images hautes et basses et le résultat du mix interieur du cercle de High dans ImageLow.
    Cdlt
    Sylvain

    Nom : Ashampoo_Snap_November 22, 2024_08h38m53s_032_.jpg
Affichages : 233
Taille : 370,1 KoNom : Ashampoo_Snap_November 22, 2024_08h29m28s_030_.jpg
Affichages : 235
Taille : 147,3 KoNom : Ashampoo_Snap_November 22, 2024_08h45m29s_034_.jpg
Affichages : 235
Taille : 222,1 KoNom : Ashampoo_Snap_November 22, 2024_08h46m14s_035_.jpg
Affichages : 236
Taille : 72,4 Ko

  14. #14
    Invité
    Invité(e)
    Par défaut
    Créer une image séparée à partir du poids faible n'a pas de sens et n'a rien de mathématique et risque de déformer les données de l'image. il faut plutôt calculer l'histogramme de l'image pour équilibrer les contrastes et pour passer a une échelle plus réduite sur 8 bit et normaliser les zones monotones pour afficher davantage de détails.

    Code pour GR32
    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
    type
      TriColor8 = packed record
        B, G, R: byte;
      end;
      pTTriColorArray = ^TTriColorArray;
      TTriColorArray = array[0..10000] of TriColor8;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      PngImage: TPngImage;
      Bitmap32: TBitmap32;
      x, y: Integer;
      pScanline: pTTriColorArray; // For accessing 16-bit grayscale data
    begin
      PngImage := TPngImage.Create;
      PngImage.LoadFromFile('C:\Users\pc\Desktop\Image16BSMALL.png');
      Bitmap32 := TBitmap32.Create;
      Bitmap32.SetSize(PngImage.Width, PngImage.Height);
      for y := 0 to PngImage.Height - 1 do
      begin
        pScanline := PngImage.ExtraScanline[y];
        for x := 0 to PngImage.Width - 1 do
        with pScanline[x] do
          Bitmap32.Pixel[x, y] := GR32.Color32(R, G, B);
      end;
     
      Bitmap32.SaveToFile('C:\Users\pc\Desktop\Image16BSMALL.bmp');
      Bitmap32.Free;
      PngImage.Free;
    end;

  15. #15
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2014
    Messages : 11
    Par défaut
    Citation Envoyé par rMist2024 Voir le message
    Créer une image séparée à partir du poids faible n'a pas de sens et n'a rien de mathématique et risque de déformer les données de l'image. il faut plutôt calculer l'histogramme de l'image pour équilibrer les contrastes et pour passer a une échelle plus réduite sur 8 bit et normaliser les zones monotones pour afficher davantage de détails.

    Code pour GR32
    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
    type
      TriColor8 = packed record
        B, G, R: byte;
      end;
      pTTriColorArray = ^TTriColorArray;
      TTriColorArray = array[0..10000] of TriColor8;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      PngImage: TPngImage;
      Bitmap32: TBitmap32;
      x, y: Integer;
      pScanline: pTTriColorArray; // For accessing 16-bit grayscale data
    begin
      PngImage := TPngImage.Create;
      PngImage.LoadFromFile('C:\Users\pc\Desktop\Image16BSMALL.png');
      Bitmap32 := TBitmap32.Create;
      Bitmap32.SetSize(PngImage.Width, PngImage.Height);
      for y := 0 to PngImage.Height - 1 do
      begin
        pScanline := PngImage.ExtraScanline[y];
        for x := 0 to PngImage.Width - 1 do
        with pScanline[x] do
          Bitmap32.Pixel[x, y] := GR32.Color32(R, G, B);
      end;
     
      Bitmap32.SaveToFile('C:\Users\pc\Desktop\Image16BSMALL.bmp');
      Bitmap32.Free;
      PngImage.Free;
    end;
    Bonjour rMist2024,
    merci !
    Si c'est un moyen de charger l'image et de la laisser en 48 bit, je vais voir cela aussi !
    Pour la question des déformations de l'image, ne pas s'inquiéter, c'est monnaie courante car un ne veut montrer de toutes façons qu'une partie de l'info !
    A bientôt
    sylvain

  16. #16
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 177
    Par défaut
    Pour la proposition du ExtraScanline par rMist2024, le code que j'ai fourni plus haut fait la même chose avec Move au lieu Pixel[] qui sur de grandes images sera un gain de performance
    Cela ne charge que la partie High 24 bits avec TriColor8 qui est la même chose que le type standard TRGBTriple (cela vient de Windows tagRGBTRIPLE)
    Attention, cela ne charge pas de 48 Bits, surtout que cela n'aurait aucun sens lorsque l'on comprend les valeurs contenues dans l'un ou l'autre, il n'y a pas de précision sur 16bits mais uniquement sur 8 bit avec une inversion

    Et on a toujours pas de votre part l'explication pourquoi chaque pixel 8 bits de Scanline sont exactement la valeur inversé de chaque pixel 8 bits de ExtraScanline,
    chaque pixel vérifie l'assertion Scanline = 255 - ExtraScanline ou si vous préférez Low.Pixel[x, y] = 255 - High.Pixel[x, y].

    Donc en réalité, la "seconde image" ne propose aucune information supplémentaire en dehors du contraste inverse sur fond noir

    Ceci a-t-il un sens pour vous d'avoir finalement deux fois la même image mais aux couleurs inversées ?
    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

  17. #17
    Invité
    Invité(e)
    Par défaut
    Pour la proposition du ExtraScanline par rMist2024, le code que j'ai fourni plus haut fait la même chose avec Move au lieu Pixel[] qui sur de grandes images sera un gain de performance
    sweiller à deux reprises (les messages #7 et #13) a envoyé des captures incorrectes qui ne correspondent pas a l'image du poids faible de l'image proposée au début de la discussion alors posté le code correcte pour créer une bitmap32.

    Si c'est un moyen de charger l'image et de la laisser en 48 bit, je vais voir cela aussi !
    Malheureusement non Bitmap32 fonctionne qu'avec le format 8 bits c'est largement suffisant pour créer des images de haute qualité le format 16 bits est plus pour le stockage et nécessite un traitement spécial pour extraire les données utiles surtout que la majorité des bibliothèques graphiques simplement ignorent le poids faible c'est à vous de décider ce qui doit être afficher ou non.. car a ce niveau l'image contient beaucoup de bruit et d’interférences.

    J'ai créé une image test 256 x 256 un dégradé de rouge de 65000 niveaux chaque pixel doit avoir une valeur unique, le but est de savoir comment combiner les deux images des deux poids, le constat est surprenant on peut imaginer les fusionner mais cette solution ne fonctionne que pour le cas présent car l"image du poids faible a une facteur de 1/256 par rapport l'autre .


  18. #18
    Invité
    Invité(e)
    Par défaut
    Ceci a-t-il un sens pour vous d'avoir finalement deux fois la même image mais aux couleurs inversées ?
    On peut assimiler à une opération de soustraction et pas inversion car pas toute l'image est inversée
    Poids faible = Valeur pixel - poids fort * 256

    les pixels sont bien quantifiés sur 16 bits c'est PngImage qui sépare les deux poids dans deux tableaux distincts le code pour le poids faible est sous compilation conditionnelle donc optionnel dans la quasi majorité des autres bibliothèques ce poids est ignoré ..pour le format rgb 16bit c'est la fonction CopyNonInterlacedRGB16 qui est utilisée pour séparer les deux poids :
    on voit bien que les octets impaires sont placées dans le tableau extra
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       //Since windows does not supports 2 bytes for
        //each R, G, B value, the method will read only 1 byte from it
        {Copy pixel values}
        Dest^ := fOwner.GammaTable[pByte(Src + 4)^]; inc(Dest);
        Dest^ := fOwner.GammaTable[pByte(Src + 2)^]; inc(Dest);
        Dest^ := fOwner.GammaTable[pByte(Src    )^]; inc(Dest);
        {$IFDEF Store16bits}
        {Copy extra pixel values}
        Extra^ := fOwner.GammaTable[pByte(Src + 5)^]; inc(Extra);
        Extra^ := fOwner.GammaTable[pByte(Src + 3)^]; inc(Extra);
        Extra^ := fOwner.GammaTable[pByte(Src + 1)^]; inc(Extra);
        {$ENDIF}

  19. #19
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 177
    Par défaut
    Citation Envoyé par rMist2024 Voir le message
    sweiller à deux reprises (les messages #7 et #13) a envoyé des captures incorrectes
    Je pense qu'il a plutôt dessiner un disque par dessus l'image "Forte", je ne sais pas pourquoi il a choisi de dessiner un disque avec des pixels aléatoire mais vu les protus visible, c'est bien la bonne image
    Même si l'on voit qu'il y a eu aussi des tentatives de mixés les deux images donnant un résultat incompréhensible (les deux images se neutralisent)


    Contrairement à ta démonstration très intéressante, cela ne semble pas du tout être ce cas sur l'image fournie !
    C'est pour cela que je doute que cela respecte le concept d'avoir une vrai palette de gris de 0 à 65000 nuances.

    Citation Envoyé par rMist2024 Voir le message
    On peut assimiler à une opération de soustraction et pas inversion car pas toute l'image est inversée
    Poids faible = Valeur pixel - poids fort * 256
    Pour l'image du post #1, la seule chose différente c'est le fond, sinon, le reste tous les pixels respecte la formule "Faible = 255 - Fort" (c'est pour moi, ce que l'on appelle une inversion des couleurs)
    Suffit d'analyser l'image, en vert chaque pixel où "Faible = 255 - Fort" est Vrai

    Franchement cela se voit nettement que c'est une inversion (VCL, Faible, Fort) ou Fort c'est l'inverse de Faible (sauf le fond) permettant d'obtenir le masque des valeurs significatives



    En fait, on pourrait voir la seconde image comme un "masque" pour la première pour différencier les pixels noir, si noir dans le deux, c'est le fond, si 255 et 0 alors c'est vrai pixel noir
    Cela permet surement avec les logiciels appropriés d'augmenter le contraste tout en conservant le fond noir mais en dehors de cela, il n'y a aucune précision supplémentaire au 8 Bits.

    Il aurait été plus simple d'avoir un PNG avec un canal Alpha pour gérer le fond.
    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

Discussions similaires

  1. Réponses: 7
    Dernier message: 24/01/2007, 11h09
  2. Utiliser une image DirectX avec GDI?
    Par Fynchi dans le forum DirectX
    Réponses: 11
    Dernier message: 02/11/2006, 10h36
  3. Réponses: 1
    Dernier message: 17/05/2006, 10h19
  4. Utiliser une image à la place du curseur par défaut
    Par nice dans le forum Interfaces Graphiques en Java
    Réponses: 3
    Dernier message: 11/12/2005, 23h15
  5. Utilise une image ISO pour le boot du PC
    Par Furius dans le forum Ordinateurs
    Réponses: 2
    Dernier message: 05/09/2005, 15h02

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