2011-02-06 3 views
3

Je cherche à dessiner une ellipse d'opacité dans CodeGear Delphi 2010.Dessiner une ellipse d'opacité dans Delphi 2010

J'avais essayé de dessiner un autre bitmap, j'avais mis la bitmap couleur transparente (pour le fond) appel la méthode de l'ellipse.

Et dans mon image je dessine le bitmap avec le paramètre d'opacité (de la surcharge). Mais ça ne marche pas.

Je veux quelque chose comme ça http://www.java2s.com/Tutorial/VBImages/WPF-UseOpacityMaskAndRadialGradientBrush.PNG

Quelqu'un sait-il une méthode de travail?

Répondre

16

Il fonctionne pour moi:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    bm1, bm2: TBitmap; 
begin 
    bm1 := TBitmap.Create; 
    bm1.LoadFromFile('C:\Users\Andreas Rejbrand\Pictures\portrait.bmp'); 

    bm2 := TBitmap.Create; 
    bm2.SetSize(bm1.Width, bm1.Height); 
    bm2.Canvas.Brush.Color := clRed; 
    bm2.Canvas.Pen.Style := psClear; 
    bm2.Canvas.Ellipse(0, 0, bm2.Width, bm2.Height); 

    Canvas.Draw(100, 100, bm1); 
    Canvas.Draw(100, 100, bm2, 127); 
end; 

Sample 1 http://privat.rejbrand.se/blendimg1.png

Si vous voulez plus de contrôle, vous pouvez toujours faire le traitement manuellement:

procedure TForm1.Button1Click(Sender: TObject); 
type 
    TRGB32Array = packed array[0..MaxInt div SizeOf(TRGBQuad)-1] of TRGBQuad; 
    PRGB32Array = ^TRGB32Array; 
    TScanline = TRGB32Array; 
    PScanline = ^TScanline; 
var 
    bm1, bm2, bm3: TBitmap; 
    sc1, sc2, sc3: PScanline; 
    i: Integer; 
    j: Integer; 
var 
    transp: real; 
const 
    opacity = 0.29; 
begin 
    transp := 1 - opacity; 

    bm1 := TBitmap.Create; 
    bm1.LoadFromFile('C:\Users\Andreas Rejbrand\Pictures\portrait.bmp'); 

    bm2 := TBitmap.Create; 
    bm2.SetSize(bm1.Width, bm1.Height); 
    bm2.Canvas.Brush.Color := clRed; 
    bm2.Canvas.Pen.Style := psClear; 
    bm2.Canvas.Ellipse(0, 0, bm2.Width, bm2.Height); 

    bm3 := TBitmap.Create; 
    bm3.SetSize(bm1.Width, bm1.Height); 

    bm1.PixelFormat := pf32bit; 
    bm2.PixelFormat := pf32bit; 
    bm3.PixelFormat := pf32bit; 

    for i := 0 to bm1.Height - 1 do 
    begin 
    sc1 := bm1.ScanLine[i]; 
    sc2 := bm2.ScanLine[i]; 
    sc3 := bm3.ScanLine[i]; 
    for j := 0 to bm1.Width - 1 do 
     with sc3^[j] do 
     begin 
     rgbBlue := round(transp*sc1^[j].rgbBlue + opacity*sc2^[j].rgbBlue); 
     rgbGreen := round(transp*sc1^[j].rgbGreen + opacity*sc2^[j].rgbGreen); 
     rgbRed := round(transp*sc1^[j].rgbRed + opacity*sc2^[j].rgbRed); 
     end; 
    end; 

    Canvas.Draw(100, 100, bm3); 

end; 

Sample 2 http://privat.rejbrand.se/blendimg2.png

Vous pouvez pour exemple laisser l'image d'arrière-plan soit à 100% opacit y en dehors de l'ellipse:

... 
    for i := 0 to bm1.Height - 1 do 
    begin 
    sc1 := bm1.ScanLine[i]; 
    sc2 := bm2.ScanLine[i]; 
    sc3 := bm3.ScanLine[i]; 
    for j := 0 to bm1.Width - 1 do 
     if sc2^[j].rgbBlue + sc2^[j].rgbGreen + sc2^[j].rgbRed = 3*255 then 
     sc3^[j] := sc1^[j] 
     else 
     with sc3^[j] do 
     begin 
      rgbBlue := round(transp*sc1^[j].rgbBlue + opacity*sc2^[j].rgbBlue); 
      rgbGreen := round(transp*sc1^[j].rgbGreen + opacity*sc2^[j].rgbGreen); 
      rgbRed := round(transp*sc1^[j].rgbRed + opacity*sc2^[j].rgbRed); 
     end; 
    end; 
    ... 

Sample 3 http://privat.rejbrand.se/blendimg3.png

Sans parler all other cool stuff you can do with pixmap manipulation:

... 
    for i := 0 to bm1.Height - 1 do 
    begin 
    sc1 := bm1.ScanLine[i]; 
    sc2 := bm2.ScanLine[i]; 
    sc3 := bm3.ScanLine[i]; 
    for j := 0 to bm1.Width - 1 do 
     if sc2^[j].rgbBlue + sc2^[j].rgbGreen + sc2^[j].rgbRed = 3*255 then 
     sc3^[j] := sc1^[j] 
     else 
     with sc3^[j] do 
     begin 
      rgbBlue := round(sin(transp*sc1^[j].rgbBlue + opacity*sc2^[j].rgbBlue)); 
      rgbGreen := round(transp*sc1^[j].rgbGreen + opacity*sc2^[j].rgbGreen); 
      rgbRed := round(transp*sc1^[j].rgbRed + opacity*sc2^[j].rgbRed); 
     end; 
    end; 
    ... 

Sample 4 http://privat.rejbrand.se/blendimg4.png

Si vous ne voulez pas vraiment le faire manuellement, je viens de comprendre , vous pouvez dessiner l'ellipse sur une copie du premier bitmap, puis fusionner ces deux bitmaps:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    bm1, bm2: TBitmap; 
begin 

    bm1 := TBitmap.Create; 
    bm1.LoadFromFile('C:\Users\Andreas Rejbrand\Pictures\portrait.bmp'); 

    bm2 := TBitmap.Create; 
    bm2.LoadFromFile('C:\Users\Andreas Rejbrand\Pictures\portrait.bmp'); 
    bm2.Canvas.Brush.Color := clRed; 
    bm2.Canvas.Pen.Style := psClear; 
    bm2.Canvas.Ellipse(0, 0, bm2.Width, bm2.Height); 

    Canvas.Draw(100, 100, bm1); 
    Canvas.Draw(100, 100, bm2, 127); 
end; 

Sample 5 http://privat.rejbrand.se/blendimg5.png

+3

+1 Mieux encore, si cela pouvait être fait avec l'anti-aliasing! –

+0

Merci pour votre solution. Merci encore! – user558126

+0

très complet d'exemples! n'oubliez pas de libérer les objets bitmap avec try..finally, mais je parie que vous le saviez déjà;) –