我的应用程序的一部分是绘制图形表单草稿,主要是用户输入表单,带有许多编辑框。我在位图上绘制并另存为 PNG,这是报告过程的所有部分,因此没有在申请表上绘制任何内容。 我绘制所有控件、编辑框、单选按钮、复选框...
绘图中最长的部分当然是绘制编辑框,因为它们的数量巨大。我有一个典型的过程,在大约 7 万个表单上绘制 100 万个编辑框。
我画了一个很简单的编辑框:
- 基本矩形,Pen 宽度 = 1
- 添加左侧和顶部附加行,以获得缩进控制的感觉。
- 根据需要添加文本
我附上了简单编辑控件的屏幕截图,放大后,可以看到额外的左线和顶线。
下面是DrawEdit的代码,绘制1M个编辑框,耗时20s。 有没有办法加快这个过程?
procedure DrawEdit(myCanvas:TCanvas; vLeft, vTop, vWidth, vHeight: integer; const vText: string; vCenterText:boolean=false);
begin
// basic rectangle
pPoint.x := vLeft; pPoint.Y := vTop;
myCanvas.Pen.Width := 1;
myCanvas.PenPos := pPoint;
myCanvas.Pen.Color := $0099A8AC;
myCanvas.LineTo(vLeft + vWidth, vTop);
myCanvas.LineTo(vLeft + vWidth, vTop + 1);
myCanvas.Pen.Color := $00E2EFF1;
myCanvas.LineTo(vLeft + vWidth, vTop + vHeight - 1);
myCanvas.LineTo(vLeft, vTop + vHeight - 1);
myCanvas.Pen.Color := $0099A8AC;
myCanvas.LineTo(vLeft, vTop);
// again top border
pPoint.x := vLeft + 1; pPoint.Y := vTop + 1;
myCanvas.PenPos := ppoint;
myCanvas.Pen.Color := $00646F71;
myCanvas.LineTo(vLeft + vWidth, vTop + 1);
// again left border
ppoint.x := vLeft + 1; ppoint.Y := vTop + 1;
myCanvas.PenPos := ppoint;
myCanvas.Pen.Color := $00646F71;
myCanvas.LineTo(vLeft + 1, vTop + vHeight - 1);
if vText<>'' then
begin
// clear area for text - white background
myCanvas.Font.Color := clblack;
myCanvas.Brush.Color := clWhite;
rRect.Left := vLeft + 2;
rRect.Top := vTop + 2;
rRect.Right := vLeft + myCanvas.TextWidth(vText);
rRect.Bottom := vTop + myCanvas.TextHeight(vText);
myCanvas.FillRect(rRect);
If Not vCenterText Then
Winapi.Windows.TextOut(myCanvas.Handle, vLeft + 4, vTop + 2, PChar(vText), Length(vText))
else
Winapi.Windows.TextOut(myCanvas.Handle, vLeft + (vWidth div 2) - (myCanvas.TextWidth(vText) div 2), vTop + (vHeight div 2) - (myCanvas.TextHeight(vText) div 2), PChar(vText), Length(vText));
end;
end;
这是我使用的测试。测试并不理想,因为真实的编辑框大小不同,但这是我测试不同优化选项的测试。
procedure TForm1.Button3Click(Sender: TObject);
var
i, t1, t2: integer;
myBitmap: TBitmap;
begin
myBitmap := TBitmap.Create;
try
myBitmap.SetSize(500, 500);
myBitmap.PixelFormat := pf24bit;
t1 := GetTickCount;
for i := 1 to 1000000 do
DrawEdit(myBitmap.Canvas, 10, 10, 100, 50, 'Edit box', true);
t2 := GetTickCount;
finally
myBitmap.Free;
end;
button3.Caption := inttostr(t2 - t1);
end;
最佳答案
GDI 可以高效地绘制到设备,但是,对于内存位图工作,它会带来很大的开销。
最好避开 GDI 层,直接对内存中的光栅图像执行此操作。我为此推荐 graphics32 库。切换到那个应该会产生非常显着的性能提升。
您可能做的另一件事是将工作分成多个任务并利用多线程。您想要绘制不同的位图,然后在最后拼接在一起。
关于delphi - 有什么方法可以加快在位图 Canvas 上的绘制速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33457952/