我期待在CodeGear Delphi 2010中绘制一个不透明椭圆.
我试图绘制另一个位图,
我设置了位图透明色(用于背景)
调用椭圆方法.
在我的图像中,我使用不透明度参数(来自重载)绘制位图.但它不起作用.
我想要这样的东西http://www.java2s.com/Tutorial/VBImages/WPF-UseOpacityMaskAndRadialGradientBrush.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.SetSize(bm1.Width,bm1.Height); bm2.Canvas.Brush.Color := clRed; bm2.Canvas.Pen.Style := psClear; bm2.Canvas.Ellipse(0,bm2.Width,bm2.Height); Canvas.Draw(100,100,bm1); Canvas.Draw(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,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,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,bm3); end;
Sample 2 http://privat.rejbrand.se/blendimg2.png
例如,您可以让背景图像在椭圆外的100%不透明度:
... 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,127); end;