2011-02-06 104 views

回答

16

它爲我的作品:

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

如果你想要更多的控制,你可以隨時手動進行處理:

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

您可以爲例如讓背景圖像處於100%不透明狀態橢圓外側y:

... 
    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

且不說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

如果你真的不想做手工,我只是想出了,可以在第一個位圖的副本上繪製橢圓,然後混合這兩個位圖:

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更妙的是,如果這是可以做到抗鋸齒! – 2011-02-07 01:06:24