在 TBitmap 周围绘制点边界线?
Drawing a borderline of dots around a TBitmap?
我写了一个例程,它应该向位图添加虚线边框:
procedure AddDottedBorderToBitmap(aBM: Vcl.Graphics.TBitmap);
var
c: TCanvas;
begin
c := aBM.Canvas;
c.Pen.Color := clBlack;
c.Pen.Mode := pmXor;
c.Pen.Style := psDot;
c.MoveTo(0, 0);
c.LineTo(0, aBM.Height - 1);
c.LineTo(aBM.Width - 1, aBM.Height - 1);
c.LineTo(aBM.Width - 1, 0);
c.LineTo(0, 0);
end;
但是当放大结果时,结果边界线而不是点似乎是由小破折号组成的:
这是正确的吗?如果不是,我怎样才能得到真正的点而不是破折号?
DrawFocusRect 这是一个 Windows API 调用,可以根据需要制作边框。
procedure AddDottedBorderToBitmap(aBM: Vcl.Graphics.TBitmap);
begin
DrawFocusRect(aBM.canvas.Handle,Rect(0,0,aBM.Width,aBM.Height));
end;
使用起来似乎很简单DrawFocusRect
,但如果您需要绘制矩形以外的其他东西,您可能需要提前阅读。
画笔样式psDot
并不是说每隔一个像素上色一个清除。如果您考虑一下,分辨率越高,就越难看出虚线与灰色实线的区别 f.ex。还有另一种笔样式 psAlternate
可以交替像素。文档说:
psAlternate
The pen sets every other pixel. (This style is applicable only for
cosmetic pens.) This style is only valid for pens created with the
ExtCreatePen API function. (See MS Windows SDK docs.) This applies to
both VCL and VCL.NET.
要定义笔并使用它,我们按如下方式进行
var
c: TCanvas;
oldpenh, newpenh: HPEN; // pen handles
lbrush: TLogBrush; // logical brush
...
c := pbx.Canvas; // pbx is a TPintBox, but can be anything with a canvas
lbrush.lbStyle := BS_SOLID;
lbrush.lbColor := clBlack;
lbrush.lbHatch := 0;
// create the pen
newpenh := ExtCreatePen(PS_COSMETIC or PS_ALTERNATE, 1, lbrush, 0, nil);
try
// select it
oldpenh := SelectObject(c.Handle, newpenh);
// use the pen
c.MoveTo(0, 0);
c.LineTo(0, pbx.Height - 1);
c.LineTo(pbx.Width - 1, pbx.Height - 1);
c.LineTo(pbx.Width - 1, 0);
c.LineTo(0, 0);
c.Ellipse(3, 3, pbx.width-3, pbx.Height-3);
// revert to the old pen
SelectObject(c.Handle, oldpenh);
finally
// delete the pen
DeleteObject(newpenh);
end;
最后是它的样子(放大镜在 x 10)
我写了一个例程,它应该向位图添加虚线边框:
procedure AddDottedBorderToBitmap(aBM: Vcl.Graphics.TBitmap);
var
c: TCanvas;
begin
c := aBM.Canvas;
c.Pen.Color := clBlack;
c.Pen.Mode := pmXor;
c.Pen.Style := psDot;
c.MoveTo(0, 0);
c.LineTo(0, aBM.Height - 1);
c.LineTo(aBM.Width - 1, aBM.Height - 1);
c.LineTo(aBM.Width - 1, 0);
c.LineTo(0, 0);
end;
但是当放大结果时,结果边界线而不是点似乎是由小破折号组成的:
这是正确的吗?如果不是,我怎样才能得到真正的点而不是破折号?
DrawFocusRect 这是一个 Windows API 调用,可以根据需要制作边框。
procedure AddDottedBorderToBitmap(aBM: Vcl.Graphics.TBitmap);
begin
DrawFocusRect(aBM.canvas.Handle,Rect(0,0,aBM.Width,aBM.Height));
end;
使用起来似乎很简单DrawFocusRect
,但如果您需要绘制矩形以外的其他东西,您可能需要提前阅读。
画笔样式psDot
并不是说每隔一个像素上色一个清除。如果您考虑一下,分辨率越高,就越难看出虚线与灰色实线的区别 f.ex。还有另一种笔样式 psAlternate
可以交替像素。文档说:
psAlternate
The pen sets every other pixel. (This style is applicable only for cosmetic pens.) This style is only valid for pens created with the ExtCreatePen API function. (See MS Windows SDK docs.) This applies to both VCL and VCL.NET.
要定义笔并使用它,我们按如下方式进行
var
c: TCanvas;
oldpenh, newpenh: HPEN; // pen handles
lbrush: TLogBrush; // logical brush
...
c := pbx.Canvas; // pbx is a TPintBox, but can be anything with a canvas
lbrush.lbStyle := BS_SOLID;
lbrush.lbColor := clBlack;
lbrush.lbHatch := 0;
// create the pen
newpenh := ExtCreatePen(PS_COSMETIC or PS_ALTERNATE, 1, lbrush, 0, nil);
try
// select it
oldpenh := SelectObject(c.Handle, newpenh);
// use the pen
c.MoveTo(0, 0);
c.LineTo(0, pbx.Height - 1);
c.LineTo(pbx.Width - 1, pbx.Height - 1);
c.LineTo(pbx.Width - 1, 0);
c.LineTo(0, 0);
c.Ellipse(3, 3, pbx.width-3, pbx.Height-3);
// revert to the old pen
SelectObject(c.Handle, oldpenh);
finally
// delete the pen
DeleteObject(newpenh);
end;
最后是它的样子(放大镜在 x 10)