2005. október 19., szerda
How to clip a TBitmap inside an irregular shape
Problem/Question/Abstract:
If I have an irregular shape, say a rectangle with the top corners rounded. How can I fill the inside of that shape with a bitmap or limit pen drawing to inside the area of the shape?
Answer:
Below is a small sample of how the problem can be resolved, using a Path converting the Path to a Region and setting the ClippingRgn:
procedure DrawHeader
var
Bmp: TBitmap;
clEnd, clStart: TColor;
R: TRect;
Rd: Integer;
Rgn: HRGN;
begin
Rd := spnTest.IntValue;
GetActiveColors(clStart, clEnd);
Bmp := TBitmap.Create;
try
R.Left := btnClipGradient.Left + btnClipGradient.Width + 20;
R.Top := btnClipGradient.Top;
R.Right := R.Left + 100;
R.Bottom := R.Top + 100;
with Bmp do
begin
Height := 20;
Width := 100;
DrawGradient(Canvas, Rect(0, 0, 100, 20), 50, goHorizontal, clStart, clEnd);
end;
with Canvas do
begin
BeginPath(Handle);
Pen.Color := clYellow;
Pen.Style := psSolid;
{Bottom line}
MoveTo(R.Left, R.Bottom);
LineTo(R.Right, R.Bottom);
{Right Line}
LineTo(R.Right, R.Top + (Rd div 2));
{Top Right}
ArcTo(Handle, R.Right - Rd + 1, R.Top, R.Right + 1, R.Top + Rd, R.Right + 1,
R.Top + (Rd div 2), R.Right - (Rd div 2) + 1, R.Top);
{Top Line}
LineTo(R.Right - (Rd div 2), R.Top);
{Top Left}
ArcTo(Handle, R.Left, R.Top, R.Left + Rd, R.Top + Rd, R.Left + (Rd div 2),
R.Top, R.Left, R.Top + (Rd div 2));
{Left line}
LineTo(R.Left, R.Top + (Rd div 2));
EndPath(Handle);
Rgn := PathToRegion(Handle);
SelectClipRgn(Handle, Rgn);
Draw(R.Left + 1, R.Top + 1, Bmp);
SelectClipRgn(Handle, HRGN(nil));
Pen.Color := clYellow;
Pen.Style := psSolid;
{Bottom line}
MoveTo(R.Left, R.Bottom);
LineTo(R.Right, R.Bottom);
{Right Line}
LineTo(R.Right, R.Top + (Rd div 2));
{Top Right}
ArcTo(Handle, R.Right - Rd + 1, R.Top, R.Right + 1, R.Top + Rd, R.Right + 1,
R.Top + (Rd div 2), R.Right - (Rd div 2) + 1, R.Top);
{Top Line}
LineTo(R.Right - (Rd div 2) + 1, R.Top);
{Top Left}
ArcTo(Handle, R.Left, R.Top, R.Left + Rd, R.Top + Rd, R.Left + (Rd div 2),
R.Top, R.Left, R.Top + (Rd div 2));
{Left line}
LineTo(R.Left, R.Bottom);
DeleteObject(Rgn);
end;
finally
Bmp.Free;
end;
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése