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

Langage Delphi Discussion :

Tableau de bytes et canvas d'un bitmap


Sujet :

Langage Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Tableau de bytes et canvas d'un bitmap
    Bonjour,

    Dans un fichier bitmap je suppose qu'il existe un tableau de bytes après l'entête du fichier.(sans doute le canvas)
    Pour une question de rapidité peut-on le récupérer dans un tableau de bytes ou de Tcolor sans être obligé de de passer par canvas.pixels[x,y] ?
    Si Oui comment ?
    Un exemple de code serait bienvenu

    Merci à tous

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    oui, avec ScanLine
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Je connais ScanLine
    Ma question est sans doute mal posée :
    Exemple : je crée le tableau "pixtab" = array of array of TColor aux dimensions d'un bitmap. Existe-t'il un autre moyen (plus rapide) que ScanLine ou Pixels pour copier l'image du bitmap dans le tableau Pixtab ? par exemple avec un pointeur ? Le canvas possède t'il un pointeur sur du tableau de Tcolor que l'on explore avec pixels ?

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 740
    Points : 13 285
    Points
    13 285
    Par défaut
    Scanline renvoi le pointeur sur le tableau. Le premier élément se trouve à ScanLine[Bitmap.Height -1]

    La seule différence est que ce tableau représente des valeurs sur 1,2 ou 4 bytes en fonction du PixelFormat et non des TColor (type générique sur 4 bytes).

  5. #5
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    Salut,

    Explorer un fichier Bitmap c'est ouvrir la boîte de Pandore tant il existe de sortes différentes de Bitmap.

    Pour en avoir une idée.

    La méthode la plus rapide est Scanline comme le suggérait Paul Toth (Scanline est un pointeur !). Reste à adapter cette méthode au format du Bitmap. Le plus aisé est sans doute le pf32bit dont l'alignement correspond à la structure de la mémoire.

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par colorid Voir le message
    Ma question est sans doute mal posée :
    Exemple : je crée le tableau "pixtab" = array of array of TColor aux dimensions d'un bitmap. Existe-t'il un autre moyen (plus rapide) que ScanLine ou Pixels pour copier l'image du bitmap dans le tableau Pixtab ? par exemple avec un pointeur ? Le canvas possède t'il un pointeur sur du tableau de Tcolor que l'on explore avec pixels ?
    oui avec ScanLine

    maintenant vu que tu ne précises absolument pas ce que tu comptes faire de cette image il est difficile de te dire ce qu'il convient de faire.

    car tu n'es pas obligé d'utiliser un Bitmap pour travailler sur une image, si tu colles un entêtre BMP à ton pixtab tu peux sauvegarder tout cela dans un fichier et obtenir un .BMP
    si tu utilises la fonction Bitlt() tu peux aussi dessiner directement ton pixtab

    bref
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Question
    Le code suivant est-il stupide ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function CopyBitmap( BMP: TBitmap):array of array of RGBTriple;
    var
      k: integer;
    begin
      with BMP do setlength(BMPCopy,Height,Width);
      for k:=0 to BMP.Height- 1 do BMPCopy[k]:= BMP.Scanline[k];
    end;
    et surtout peut-on l'utiliser dans une DLL ?

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Correction
    On définit un type telque :
    TBMPCopy = array of array of RGBTriple;
    on utilise le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function CopyBitmap( BMP: TBitmap):TBMPCopy;
    var
      k: integer;
    begin
      with BMP do setlength(result,Height,Width);
      for k:=0 to BMP.Height- 1 do result[k]:= BMP.Scanline[k];
    end;
    Peut-on utiliser cette fonction dans une DLL ?

  9. #9
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par colorid Voir le message
    On définit un type telque :
    TBMPCopy = array of array of RGBTriple;
    on utilise le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function CopyBitmap( BMP: TBitmap):TBMPCopy;
    var
      k: integer;
    begin
      with BMP do setlength(result,Height,Width);
      for k:=0 to BMP.Height- 1 do result[k]:= BMP.Scanline[k];
    end;
    Peut-on utiliser cette fonction dans une DLL ?
    oui c'est stupide

    comme indiqué par AndNotOr "BMP.ScanLine[BMP.Height -1]" est un pointeur vers le tableau des pixels de l'image.

    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
     
    procedure TForm1.FormCreate(Sender: TObject);
    type
      TPixels = array[0..511, 0..511] of TColor;
    var
      bmp :TBitmap;
      pixels: ^TPixels;
      index : Integer;
    begin
      bmp := TBitmap.Create;
      bmp.PixelFormat := pf32Bit;
      bmp.Width := 512;
      bmp.Height := 512; // ou -512, cf plus bas
      pixels := BMP.ScanLine[511];
      fillchar(pixels^, sizeof(TPixels), $c0);
      for index := 0 to 511 do
        pixels[index, index] := (index and 255)  + (255 - index and 255) shl 8 + ((128 + 2 * index) and 255) shl 16;
      Image1.Picture.Assign(bmp);
      bmp.Free;
    end;

    il faut noter que par défaut un Bitmap a la tête en bas... mais il est possible de le redresser en spécifiant une hauteur < 0, -512 dans mon exemple.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Deux questions
    Bonjour Paul TOTH
    1) dans l'exemple l'image est carrée 511x511) quel serait le code pour une image 640x480 ?
    2) Toujours dans l'exemple le tableau est dimentionné celà pourrait marcher dans une DLL, mais est-il possible d'utiliser des tablesux dynamiques dans des fonctions DLL ?
    Merci pour tout

  11. #11
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par colorid Voir le message
    Bonjour Paul TOTH
    1) dans l'exemple l'image est carrée 511x511) quel serait le code pour une image 640x480 ?
    c'est une vraie question ?

    Citation Envoyé par colorid Voir le message
    2) Toujours dans l'exemple le tableau est dimentionné celà pourrait marcher dans une DLL, mais est-il possible d'utiliser des tablesux dynamiques dans des fonctions DLL ?
    Merci pour tout
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Pas compris
    Je ne vois pas comment paramétrer le tableau pour unr image 640x480
    voici l'essai :
    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
    procedure TForm4.FormCreate(Sender: TObject);
    type
      TPixels = array[0..511, 0..511] of TColor;
    var
      bmp :TBitmap;
      pixels: ^TPixels;
      w,h : Integer;
    begin
      bmp := TBitmap.Create;
      bmp.PixelFormat := pf32Bit;
      bmp.Width := 640;
      bmp.Height := 480; // ou -512, cf plus bas
      pixels := BMP.ScanLine[bmp.Width*bmp.Width];
      fillchar(pixels^, sizeof(TPixels), $c0);
      for h := 0 to bmp.Height-1 do
        for w := 0 to bmp.Width-1 do
          pixels[h, w] := clblack;
      Image1.Picture.Assign(bmp);
      bmp.Free;
    end;
    génère le messagte 'Indice ligne hors limite"

    Merci de m'expliquer

  13. #13
    Membre chevronné

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 289
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2002
    Messages : 1 289
    Points : 1 940
    Points
    1 940
    Par défaut
    As-tu regardé quel était le nom du paramètre de ScanLine? L'as-tu comparé à la valeur que tu lui passais?

    Pour information
    http://nono40.developpez.com/tutorie.../efg/scanline/
    Delphi 7/XE2/XE3
    C#
    Oracle 9i à 12c
    SQL Server 2008 à 2022

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Le code suivant ne fonctionne pas
    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
    procedure TForm4.FormCreate(Sender: TObject);
    type
      TPixels = array[0..511, 0..511] of TColor;
    var
      bmp :TBitmap;
      P : PByteArray;
      w,h : Integer;
    begin
      bmp := TBitmap.Create;
      bmp.PixelFormat := pf32Bit;
      Bmp.LoadFromFile('c:\1.bmp');
      for h := 0 to bmp.Height-1 do
      begin
        P := Bmp.ScanLine[h];
        for w := 0 to bmp.Width-1 do
          P[w]:= h;
      end;
      Image1.Picture.Assign(bmp);
      bmp.Free;
    end;
    L'image se trouve divisée en trois parties deux partie à gauche en dégrdé noir au blanc et une partie à droite correspondante à une portion de l'image originale

    Où est l'erreur ?

  15. #15
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    1)
    Je ne vois pas comment paramétrer le tableau pour unr image 640x480
    voici l'essai :
    ...
    génère le messagte 'Indice ligne hors limite"
    Forcément, car dans ton post de 09h49 tu as conservé TPixels = array[0..511, 0..511] of TColor;
    mais modifié :
    bmp.Width := 640;
    bmp.Height := 480;
    ... faudrait donc également modifier les limites du TPixels.

    2) A part ceci, tu peux trouver ici : http://stackoverflow.com/questions/3...n-for-delphi-7

    une autre façon de créer un tableau donnant accès direct aux commposantes d'un pixel et utiisant le type suivant :
    type
    TPixmap = array of packed array of RGBQUAD; // pour du pf32bit mais modifiable en pf24bit en passant en RGBTriple.

    Voir la procédure TForm3.DrawAntialisedLineOnPixmap(var Pixmap: TPixmap; const AX1, AY1, AX2, AY2: real; const LineColor: TColor);

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 519
    Points : 25 037
    Points
    25 037
    Par défaut
    Déjà, un indice [0..511, 0..511] cela fait 512 x 512 !
    Tu as deux valeurs à changer 511 par 639 et 479 ... essaye dans un sens puis dans l'autre, tu verras lequel passe !
    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
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    Posts-croisés.

    ... et dans ton code de 11h09 il faudrait aussi remettre
    bmp.Width := 640;
    bmp.Height := 480;
    qui existaient dans le code de 09h49

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Un PByteArray qui semble fonctionner
    avec le code suivant l'image affichée est correcte :
    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
    procedure TForm4.FormCreate(Sender: TObject);
    var
      P : PByteArray;
      bmp :TBitmap;
      w,h : Integer;
    begin
      bmp := TBitmap.Create;
      bmp.PixelFormat := pf24Bit;
      Bmp.LoadFromFile('c:\1.bmp');
      for h := 0 to bmp.Height-1 do
      begin
        P := Bmp.ScanLine[h];
        for w := 0 to bmp.Width-1 do
          P[h]:= w;
      end;
      Image1.Picture.Assign(bmp);
      bmp.Free;
    end;
    Si P est une variable générale, connaissant bmp.Width et bmp.Height Comment recréer l'image à partir de P ?
    Un exemple code serait bien venu

  19. #19
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-salut,

    avec le code suivant l'image affichée est correcte :
    ... c'est normal car les boucles n'influent ici pas sur l'affichge.


    Si P est une variable générale, connaissant bmp.Width et bmp.Height Comment recréer l'image à partir de P ?
    ... avec P := Bmp.ScanLine[h];
    tu ne stockes que la dernière ligne du BitMap donc tu ne pas recréer l'image à partir de P.

    Il faut donc stocker autant de P qu'il y a de lignes donc créer une variable globale du type tMesLignes = array of PByteArray
    pré-dimensionnée avec un SetLength(MesLignes,Bmp.height)
    et ensuite tu y stockes les lignes.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Socket][File] Envoyer un tableau de byte
    Par itsmii dans le forum Entrée/Sortie
    Réponses: 14
    Dernier message: 30/01/2014, 09h10
  2. Création de bitmap à partir d'un tableau de byte
    Par Phenix26 dans le forum Windows
    Réponses: 2
    Dernier message: 06/12/2007, 20h30
  3. probleme d allocation avec un tableau de BYTE
    Par e1lauren dans le forum C++
    Réponses: 5
    Dernier message: 06/05/2005, 13h42
  4. [VB.NET] Tableau de bytes Lecture/Ecriture
    Par BenoitM dans le forum Windows Forms
    Réponses: 3
    Dernier message: 05/04/2005, 09h51
  5. [C#] Convertir un tableau de byte en Image
    Par goulhasch dans le forum ASP.NET
    Réponses: 4
    Dernier message: 24/01/2005, 10h12

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