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 :

Problème de pointeur


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 13
    Points : 12
    Points
    12
    Par défaut Problème de pointeur
    Bonjours,
    J’ai besoin d’avoir accès aux valeurs RGB et YUV d’une image sans les recalculer chaque fois pour cela j’ai crée un nouveau type mais sa prend trop de place si je les réécris chaque fois donc je dois le faire avec des pointeurs (je n’aime pas trop,car je début avec les pointeurs, mais je n’ai pas le choix).

    TYPE
    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
     
    type
    //RGB+Alpha
      PPixel32 = ^TPixel32;
      TPixel32 = packed record case integer of
        0 : (Color      : integer);
        1 : (B, G, R, A : byte);
      end;
      PPixels32 = ^TPixels32;
      TPixels32 = packed array[0..0] of TPixel32;
    //YUV
      PYUV = ^TYUV;
      TYUV=record
          Y,U,V:real;
      end;
    // RGBA+YUV
      PPixel=^TPixel;
      TPixel=record
         RGBA:PPixel32;
         YUV:PYUV;
      end;
      PPixels=^Tpixels;
      TPixels=array[0..639] of PPixel;
      Pimages=^Timages;
      Timages=array[0..479] of PPixels;
    Procédure
    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
     
    Procedure Tcouleur.convertiseur(bmp:Tbitmap; var image:Pimages);
    var   Pbmp:PPixels32;
          I:Integer;
          J: Integer;
          LYUV:TYUV;
          A:Tpixel;
          B:Tpixels;
    begin
    for I := 0 to 479 do
      begin
        Pbmp:=bmp.ScanLine[I];
        for J := 0 to 639 do
          begin
     
            // tout les conversions
            begin      //copie des RGBA
              A.RGBA:=ppixel32(Pbmp[j]);
            end;
            begin      //conversion des RGB en YUV
                LYUV.Y:=0.299*A.RGBA.R + 0.587*A.RGBA.G + 0.114*A.RGBA.B;
                LYUV.U:=0.492*( A.RGBA.B- LYUV.Y)+128;
                LYUV.V:=0.877*( A.RGBA.R - LYUV.Y)+128;
            A.YUV:=@LYUV;
            end;
            B[J]:=@A;
          end;
        image[I]:=@B;
      end;
    end;
    J’ai deux problème le premier est que je pointe toujours sur la même adresse mémoire donc j ai toujours les mêmes valeurs (se qui est logique mais je ne vois pas comment le résoudre).
    Le second est que j ai une violation accès mémoire et je ne vois pas d’où elle peut bien venir.
    Merci d’avance

  2. #2
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    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
     
    Unit RGBYUV;
     
    interface
     
    uses Windows, SysUtils;
     
    type
      PRGBA = ^TRGBA;
      TRGBA = packed record case integer of
        0 : (Color : integer);
        1 : (B, G, R, A : byte);
      end;
     
      PYUV = ^TYUV;
      TYUV= packed record
          Y, U, V: single;
      end;
     
      TPixel = record
        RGBA : TRGBA;
        YUV : TYUV;
      end;
     
      TYUVImage = array of array of TPixel;
     
    procedure BitmapYUV(BMP : TBitmap; var YUVImage : TYUVImage);
     
    implementation
     
    var
      PrecalcYR, PrecalcYG, PrecalcYB : array[byte] of single;
     
    procedure InitializePrecalcYRGB;
    var N : integer;
    begin
      for N := 0 to 255 do
      begin
        PrecalcYR[N] := N * 0.299;
        PrecalcYG[N] := N * 0.587; 
        PrecalcYB[N] := N * 0.114; 
      end;
    end;
     
    procedure BitmapYUV(BMP : TBitmap; var YUVImage : TYUVImage);
    var
      Y, X, W, H : integer;
      SL : PRGBA;
    begin
      if BMP.PixelFormat <> pf32bit then
        BMP.PixelFormat := pf32bit;
     
      SetLength(YUVImage, BMP.Height, BMP.Width);
     
      W := BMP.Width-1;
      H := BMP.Height-1;
      SL := BMP.ScanLine[BMP.Height-1];
      for Y := 0 to H do
        for X := 0 to W do
        begin
          YUVImage[Y,X].RGBA := SL^;
          YUVImage[Y,X].YUV.Y := PrecalcYR[SL^.R] + PrecalcYG[SL^.G] + PrecalcYB[SL^.B];
          YUVImage[Y,X].YUV.U := 0.492*(SL^.B-YUVImage[Y,X].YUV.Y) + 128;
          YUVImage[Y,X].YUV.V := 0.877*(SL^.R-YUVImage[Y,X].YUV.Y) + 128;
          inc(SL);
        end;
    end;
     
    initialization
      InitializePrecalcYRGB;
     
    end.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Merci pour cette réponse et je me souviendrai de la technique qui consiste à calculer les 3* 256 possibilités à l’avance.

    Mais je ne comprends pas bien comment on peut récupère tout les pixels à partir d’un seul scanline
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SL := BMP.ScanLine[BMP.Height-1]

  4. #4
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    methode 1 sans précalcul (zone boucle) :
    1 536 000 multiplications sur réel
    1 228 800 additions sur réel
    614 400 soustraction sur réel
    480 appels à scanline = 48 000 instructions supplémentaires~/+
    1 843 200 assignations
    = 5 270 880 opérations~

    methode 2 avec précalcul (zone boucle) :
    614 400 multiplications sur réel
    1 228 800 additions sur réel
    614 400 soustraction sur réel
    0 appel à scanline
    1 228 800 assignations
    307 200 incrementations
    =4 083 600 opérations~




    le bloc memoire utilisé par le bitmap est "packé" dans cette dernière.

    pas de blanc, pas de trou, pas de données disséminées par ci par la.

    scanline, fournis un pointeur qui vas pointé sur chaque "ligne" du bitmap.

    en fait, c'est une seul est unique ligne de donnée, le pointeur est juste incrémenté de "largeur du bitmap*taille des pixels" et l'objet TBitmap via la propriété scanline permet de lire ceci comme si c'etait un tableau à deux dimension.

    Scanline[Height-1] pointe tout simplement sur le début du bloc memoire du bitmap, en gros, sur le tout premier pixel.
    mais plutôt que d'incrémenter, ligne par ligne, nous incrementons pixels par pixels, sans coupure et sans réappeler ou calculer le pointeur d'origine via scanline.

    si tu es curieux, fait un clic droit dans l'ide sur une déclaration de Bitmap.Scanline et ensuite "chercher la déclaration".
    il t'amera dans Graphics.TBitmap -> propriété ScanLine
    répète l'opération sur le reader de ScanLine (GetScanLine je crois).
    regarde son implémentation, c'est ceci qu'on évite de rappeler X milliers de fois dans la boucle.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 13
    Points : 12
    Points
    12
    Par défaut
    Merci beaucoup

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

Discussions similaires

  1. Problème de pointeurs..embrouillé
    Par Frenchy dans le forum C++
    Réponses: 11
    Dernier message: 10/03/2005, 16h33
  2. Problème de pointeur avec un TQuery
    Par Oluha dans le forum Bases de données
    Réponses: 3
    Dernier message: 25/01/2005, 13h57
  3. Problème de pointeur
    Par toma_lille dans le forum C++
    Réponses: 1
    Dernier message: 07/12/2004, 21h26
  4. [MFC] Problème de pointeur !!
    Par acastor dans le forum MFC
    Réponses: 7
    Dernier message: 19/03/2004, 15h50
  5. TBitmap et problèmes de pointeurs...
    Par benj63 dans le forum C++Builder
    Réponses: 8
    Dernier message: 28/07/2003, 13h39

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