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 :

Région quelconque par bitmap?


Sujet :

Langage Delphi

  1. #1
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut Région quelconque par bitmap?
    Comment puis je faire pour définir une région a partir d'un bitmap?

    suis je obligé de faire des tableaux manuellement des points décrivant mes régions?
    au mieux, j'ai vu un utilitaire qui permet de crée un fichier d'une région par clic de souris, ce qui ne me rassure pas beaucoup.
    es ce si fastudieux de crée des régions complexes alors qu'avec un bitmap n/b on pourrais définir les points visible et non visible (un masque de la région)?

    au pire:
    faut-il récupérer les points à partir d'un logiciel de vectorisation?
    ou dois je me lancer dans la programmation d'un utilitaire?

    aurais je manqué une fonction dans la sdk, une astuce?

    merci d'avance de m'éclairer sur la question.

  2. #2
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 670
    Points : 7 040
    Points
    7 040
    Par défaut Re: Région quelconque par bitmap?
    Citation Envoyé par vodiem
    Comment puis je faire pour définir une région a partir d'un bitmap?
    J'avais trouvé ça :
    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
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    function BitmapToRegion(bmp: TBitmap; TransparentColor: TColor=clBlack; RedTol: Byte=1; GreenTol: Byte=1; BlueTol: Byte=1): HRGN;
    const
       AllocUnit = 100;
    type
       PRectArray = ^TRectArray;
       TRectArray = Array[0..(MaxInt div SizeOf(TRect))-1] of TRect;
    var
       pr: PRectArray;    // used to access the rects array of RgnData by index
       h: HRGN;           // Handles to regions
       RgnData: PRgnData; // Pointer to structure RGNDATA used to create regions
       lr, lg, lb, hr, hg, hb: Byte; // values for lowest and hightest trans. colors
       x,y, x0: Integer;  // coordinates of current rect of visible pixels
       b: PByteArray;     // used to easy the task of testing the byte pixels (R,G,B)
       ScanLinePtr: Pointer; // Pointer to current ScanLine being scanned
       ScanLineInc: Integer; // Offset to next bitmap scanline (can be negative)
       maxRects: Cardinal;   // Number of rects to realloc memory by chunks of AllocUnit
    begin
       Result := 0;
       // Keep on hand lowest and highest values for the "transparent" pixels
       lr := GetRValue(TransparentColor);
       lg := GetGValue(TransparentColor);
       lb := GetBValue(TransparentColor);
       hr := Min($ff, lr + RedTol);
       hg := Min($ff, lg + GreenTol);
       hb := Min($ff, lb + BlueTol);
       // ensures that the pixel format is 32-bits per pixel 
       bmp.PixelFormat := pf32bit;
       // alloc initial region data
       maxRects := AllocUnit;
       GetMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects));
       try
          with RgnData^.rdh do
          begin
             dwSize := SizeOf(RGNDATAHEADER);
             iType := RDH_RECTANGLES;
             nCount := 0;
             nRgnSize := 0;
             SetRect(rcBound, MAXLONG, MAXLONG, 0, 0);
          end;
          // scan each bitmap row - the orientation doesn't matter (Bottom-up or not)
          ScanLinePtr := bmp.ScanLine[0];
          ScanLineInc := Integer(bmp.ScanLine[1]) - Integer(ScanLinePtr);
          for y := 0 to bmp.Height - 1 do
          begin
             x := 0;
             while x < bmp.Width do
             begin
                x0 := x;
                while x < bmp.Width do
                begin
                   b := @PByteArray(ScanLinePtr)[x*SizeOf(TRGBQuad)];
                   // BGR-RGB: Windows 32bpp BMPs are made of BGRa quads (not RGBa)
                   if (b[2] >= lr) and (b[2] <= hr) and (b[1] >= lg) and (b[1] <= hg) and (b[0] >= lb) and (b[0] <= hb) then
                      Break; // pixel is transparent
                   Inc(x);
                end;
                // test to see if we have a non-transparent area in the image
                if x > x0 then
                begin
                   // increase RgnData by AllocUnit rects if we exceeds maxRects 
                   if RgnData^.rdh.nCount >= maxRects then
                   begin
                      Inc(maxRects,AllocUnit);
                      ReallocMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects));
                   end;
                   // Add the rect (x0, y)-(x, y+1) as a new visible area in the region
                   pr := @RgnData^.Buffer; // Buffer is an array of rects
                   with RgnData^.rdh do
                   begin
                      SetRect(pr[nCount], x0, y, x, y+1);
                      // adjust the bound rectangle of the region if we are "out-of-bounds"
                      if x0 < rcBound.Left then   rcBound.Left := x0;
                      if y < rcBound.Top then   rcBound.Top := y;
                      if x > rcBound.Right then   rcBound.Right := x;
                      if y + 1 > rcBound.Bottom then   rcBound.Bottom := y + 1;
                      Inc(nCount);
                   end;
                end; // if x > x0
                // Need to create the region by muliple calls to ExtCreateRegion, 'cause
                // it will fail on Windows 98 if the number of rectangles is too large
                if RgnData^.rdh.nCount = 2000 then
                begin
                   h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects), RgnData^);
                   if Result > 0 then
                   begin   // Expand the current region
                      CombineRgn(Result, Result, h, RGN_OR);
                      DeleteObject(h);
                   end
                   else   // First region, assign it to Result
                      Result := h;
                   RgnData^.rdh.nCount := 0;
                   SetRect(RgnData^.rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
                end;
                Inc(x);
             end;   // scan every sample byte of the image
             Inc(Integer(ScanLinePtr), ScanLineInc);
          end;
          // need to call ExCreateRegion one more time because we could have left
          // a RgnData with less than 2000 rects, so it wasn't yet created/combined
          h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects), RgnData^);
          if Result > 0 then
          begin
             CombineRgn(Result, Result, h, RGN_OR);
             DeleteObject(h);
          end
          else
             Result := h;
       finally
          FreeMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects));
       end;
    end;
    Ca marche plutôt bien ...


  3. #3
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    Ok,
    J'étudie ca, et merci BEAUCOUP Lung!

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

Discussions similaires

  1. [GD] Remplir une forme quelconque par une couleur est-ce possible avec GD ?
    Par cjean123 dans le forum Bibliothèques et frameworks
    Réponses: 10
    Dernier message: 15/04/2014, 13h02
  2. remplir une région avec un bitmap
    Par julius1983 dans le forum API, COM et SDKs
    Réponses: 5
    Dernier message: 17/11/2009, 15h13
  3. Réponses: 3
    Dernier message: 09/10/2007, 19h04
  4. Réponses: 4
    Dernier message: 10/07/2007, 15h17
  5. Réponses: 37
    Dernier message: 28/04/2005, 08h47

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