Free Tools

Programmez!



Sélection logiciels

1. Avast! Edition Familiale 4.7

2. Prism 0.9

3. Google Earth 4

4. XAMPP 1.6.8

5. Messenger Plus! Live


En bref

14 Nov 2008 [Évènement] YouTube Live : diffusion en direct du concert YouTube !

08 Nov 2008 Faille WiFi : 15 minutes pour casser une clé WPA

06 Nov 2008 Aidez MySpace à s'enrichir : Piratez !

31 Oct 2008 Ubuntu 8.10 : En téléchargement dès aujourd'hui !

28 Oct 2008 Microsoft Surface : le futur de l'informatique est pour maintenant !

Consulter les archives


Les derniers dossiers


Les ressources Delphi et C/C++

Remplacer un caractère par un autre (compatible Unicode Delphi2009)

Converter - Conversions d'unités de longueur

Variables globales en C

Music Pro Package

Afficher la date et heure du jour


Membres en ligne


Nos partenaires

Espacerezo

KilaSoft


À votre tour, devenez partenaire de mx-dev.net.



Vous êtes ici : AccueilForumProg DelphiBitmap 32 bitsPage 2


Bitmap 32 bits




Deefaze
Membre

Avatar de Deefaze

Inscrit le 07 Juil 2008

20 messages
26 points

Profil

Posté le Lundi 07 Juillet 2008 à 02:35

   TPixel32 = packed record
     Blue : byte;
     Green: byte;
     Red  : byte;
     Alpha: byte;
   end;

 

aie ... packed compresse les données, malheureusement ça ralentis l'accés a ces dernieres.

de plus, les bitmap ne sont pas vraiment afféctés par l'alpha ... les bitmap 32 bits sont assé inutile, une sorte d'aberation.

travailler en 24bit peut etre mieux, surtout quand on travail sur les bytes, si on travail sur la couleur (integer) la c'est sur qu'il vaux mieux travailler en 32bits puisque les registre 32bit sont plus performants.... même si c'est que quelques nanosecondes mieux.

 

moi j'utilise ceci :

 type
  TPixelBytesOrder = (
    bcBlue  = 0,
    bcGreen = 1,
    bcRed   = 2,
    bcAlpha = 3
  );
  pPixelQuad = ^TPixelQuad;
  TPixelQuad  = array[TPixelBytesOrder] of byte;

function ColorToPixelQuad(const Color: TColor): TPixelQuad; {$IFDEF RTLVersion >= 18.0} inline; {$ENDIF}
begin
  result[bcBlue]  := byte(color shr 16);
  result[bcGreen] := byte(color shr 8);
  result[bcRed]   := byte(color);
  result[bcAlpha] := byte(color shr 24);
end;

function PixelQuad(const R,G,B,A: byte): TPixelQuad; overload; {$IFDEF RTLVersion >= 18.0} inline; {$ENDIF}
begin
  result[bcBlue] := B;
  result[bcGreen]:= G;
  result[bcRed]  := R;
  result[bcAlpha]:= A;
end;

function PixelQuad(const R,G,B: byte): TPixelQuad; overload; {$IFDEF RTLVersion >= 18.0} inline; {$ENDIF}
begin
  result[bcBlue] := B;
  result[bcGreen]:= G;
  result[bcRed]  := R;
  result[bcAlpha]:= 0;
end;


exemple :


procedure TForm1.FormCreate(Sender: TObject);
var
  pX : pPixelQuad;
  N  : integer;
  BMP: Tbitmap;
begin
  BMP := TBitmap.Create;
  BMP.Assign(Image1.Picture.Bitmap);
  BMP.PixelFormat := pf32bit;
  try
    pX := BMP.ScanLine[BMP.Height-1];
    for N := 0 to (BMP.Width*BMP.Height)-1 do
    begin
      pX^ := PixelQuad(255, 128, 64); // sauce tomate :)
      inc(pX);
    end;
    image1.Picture.Bitmap.Assign(BMP);
  finally
    BMP.Free;
  end;
end;

 

 

pour ton cas, si tu tiens a garder le record et si tu possede delphi 2006/2007 tu peu t'amuser a faire un truc du genre :

type
  pPixel24 = ^TPixel24;
  TPixel24 = record
    B,G,R : byte;
    class operator IMPLICIT(C: TColor): TPixel24; inline;
  end;

{ TPixel24 }

class operator TPixel24.IMPLICIT(C: TColor): TPixel24;
begin
  result.B := byte(C shr 16);
  result.G := byte(C shr 8);
  result.R := byte(C);
end;

exemple :


procedure TForm1.FormCreate(Sender: TObject);
var
  pX : pPixel24;
  N  : integer;
  BMP: Tbitmap;
begin
  BMP := TBitmap.Create;
  BMP.Assign(Image1.Picture.Bitmap);
  BMP.PixelFormat := pf24bit;
  try
    pX := BMP.ScanLine[BMP.Height-1];
    for N := 0 to (BMP.Width*BMP.Height)-1 do
    begin
      pX^ := TColor(clBLue);
      pX^ := TColor($FF0000);
      inc(pX);
    end;
    image1.Picture.Bitmap.Assign(BMP);
  finally
    BMP.Free;
  end;
end;     

 

 

 

PS : desolé pour le double poste, mais j'ai été deconécté entre deux, le temps de rediger le message. :)

Flo
Membre

Avatar de Flo

Inscrit le 13 Août 2007

30 messages
77 points

Profil

Posté le Lundi 07 Juillet 2008 à 11:06

Y'a pas de quoi pour le double-post ! C'est réglé.

Ta technique "implicite" est excellente mais évidemment, tout le monde n'a pas delphi 2006/7.

Sinon, pour le "packed", c'est pas compressé au sens Win-zip du terme, mais plutôt "compacté".

Cela signifie simplement qu'en mémoire tu as ça : BGRA (une lettre = un octet)

Si tu ne met pas packed, Delphi aligne les débuts des variables selon la directive {$A} qui vaut 8 par défaut, et tu obtiens ça: B000G000R000A000, tout ça pour respecter l'alignement sur DWord.

Mais ici, il ne faut pas, puisque dans le fichier, les octets des composantes sont bien côte à côte.

 

Deefaze
Membre

Avatar de Deefaze

Inscrit le 07 Juil 2008

20 messages
26 points

Profil

Posté le Marsdi 08 Juillet 2008 à 12:54

bien vus.

peut etre limité l'utilisation du packed en redefinissant $A a 1 pour un byte align, pour la declaration de TPixel.

faudrait faire des mesures de perf d'accés.

Thwilliam
Membre

Ce membre n'a pas d'avatar

Inscrit le 14 Oct 2007

6 messages
9 points

Profil

Posté le Marsdi 08 Juillet 2008 à 12:55

Salut Deefaze & Florent.

 @Deefaze :

D'accord avec toi pour les bitmaps 32bits, c'est assez inutile si on n'emploie pas la couche alpha. J'ai d'ailleurs toujours utilisé le traitement sur 24 bits. Mais je pensais que le traitement sur les octets pouvait être optimisé en 32 bits, ce qui semble assez logique dans une architecture 32 bits (?).

Pour l'utilisation de "packed" : il faudrait se mettre d'accord, car beaucoup de sources graphiques sérieuses l'utilisent. Delphi lui-même dans windows.pas déclare :

TRGBTriple = PACKED RECORD
  rgbtBlue : BYTE;
  rgbtGreen: BYTE;
  rgbtRed  : BYTE;
END;

Merci pour le code que tu utilises personnellement.

A +

Thierry

Deefaze
Membre

Avatar de Deefaze

Inscrit le 07 Juil 2008

20 messages
26 points

Profil

Posté le Mercredi 09 Juillet 2008 à 10:12

 

En fait tout depend de ce que tu compte faire sur le bitmap.

par exemple, un filtre negatif tu le fait en 32bit avec un integer c'est plus simple.

 

procedure Negativize(src, dest : TBitmap); // ~0.026 cycles par pixel
var X : integer;
    pPix : ^Integer;
begin
  Dest.Assign(Src);
  Dest.PixelFormat := pf32Bit;

  pPix := Dest.ScanLine[Dest.Height-1];
  for X := 0 to (Dest.Width*Dest.Height)-1 do
  begin
    pPix^ := not pPix^;
    inc(pPix);
  end;
end;

pouf, rapide, efficace.

 

par contre quand c'est du traitement sur R,G,B, par exemple un GrayScale, la on peu travailler en 24bits ou en 32bits. perso, il est vrai que je travail en 32bits a chaque fois.
surtout quand il sagit de filtre, qui ne necessite pas forcement d'avoir un rendus immediat par rapport a des effets temps réel ou la, il faut chercher le plus performant.

 

procedure TrueGrayScale(Src,Dest : TBitmap); // ~0.050 cycles par pixel
var
  X  : integer;
  Bo : integer;
  pPix : pByteQuad;
  PCLR : array[0..255] of single;
  PCLG : array[0..255] of single;
  PCLB : array[0..255] of single;
const
  LumRed   = 0.2125; // % of red
  LumGreen = 0.7154; // % of green
  LumBlue  = 0.0721; // % of blue
                     // = 100% (1.0)
begin
  Dest.Assign(Src);
  Dest.PixelFormat := pf32Bit;

  { PreCalculs }
  for X := 0 to 255 do
  begin
    PCLR[X] := X*LumRed;
    PCLG[X] := X*LumGreen;
    PCLB[X] := X*LumBlue;
  end;

  pPix := Dest.ScanLine[Dest.Height-1];
  for X := 0 to (Dest.Width*Dest.Height)-1 do
  begin
    Bo := byte(Round(PCLB[pPix^[0]] + PCLG[pPix^[1]] + PCLR[pPix^[2]]));
    pPix^[0] := Bo;
    pPix^[1] := Bo;
    pPix^[2] := Bo;
    inc(pPix);
  end;
end;
 

perso, j'ai jamais utiliser le TRGBTriple. ou même les fonction GetRedValue etc. je prefere utiliser mes propres methodes.

Thwilliam
Membre

Ce membre n'a pas d'avatar

Inscrit le 14 Oct 2007

6 messages
9 points

Profil

Posté le Mercredi 09 Juillet 2008 à 15:14

Salut Deefaze,

Encore merci à toi.

A +

Thierry 

 


Pages : 1 2


Participer à cet échange :

Pour participer à cet échange, vous devez vous connecter.