我创建了一个打印预览对象,允许我将来自不同来源的多个图形对象组织到打印页面上。
为了在打印机画布上渲染这些对象,我必须首先将它们渲染为计算大小的位图,然后使用canvas.draw(x,y,bitmap)将位图渲染到正确位置的Tprinter画布。方法。
我很早就发现需要一个独立于设备的位图,并将像素格式设置为pf24bit。
在办公室HP laserjet上试过这个,工作正常,HP color Deskjet工作正常,但Cannon彩色打印机无法正常工作或偶尔在随机点上提供间歇性图形。
现在,如果我将图形对象直接渲染到打印机画布,那么所有工作都可以。
直接渲染到打印机画布但由于各种原因,对我来说不是一个可行的长期解决方案。
所以,我的问题是,Tprinter.canvas是什么让它依赖于硬件,是否有任何解决方法?
一些示例代码将页面划分为4个象限,带有边距和单元格填充,并在每个象限中放置一个图形对象。每个图形对象都有一个绘制图形的RenderToBitmap方法。
procedure TMultiPrintForm.PrintBtnClick(Sender: TObject);
var w,h,h2,w2,mv,iw,ih,pv,cw,ch:integer; Abmp:Tbitmap;
begin
Abmp:=Tbitmap.create;
Abmp.PixelFormat := pf24bit;
try
with Printer do
begin
w:=pagewidth;
h:=pageheight;
h2:=h div 2;
w2:=w div 2;
mv:=h*margin.value div 200; //margin percentage div 2
pv:=h*padding.value div 400; //padding percentage div 4
iw:=w-mv; //internal width
ih:=h-mv; //internal height
cw:=(iw-mv) div 2-pv; //Quadrant Cell Width
ch:=(ih-mv) div 2-pv; //Quadrant Cell Height
Abmp.width:=cw;
Abmp.height:=ch;
If Fsources[0]<>nil then
begin
Fsources[0].rendertoBitmap(Abmp);
canvas.draw(mv,mv,Abmp);
end;
If Fsources[1]<>nil then
begin
Fsources[1].rendertoBitmap(Abmp);
canvas.draw(w2+pv,mv,Abmp);
end;
If Fsources[2]<>nil then
begin
Fsources[2].rendertoBitmap(Abmp);
canvas.draw(mv,h2+pv,Abmp);
end;
If Fsources[3]<>nil then
begin
Fsources[3].rendertoBitmap(Abmp);
canvas.draw(w2+pv,h2+pv,Abmp);
end;
end;
finally
printer.Enddoc;
Abmp.free;
end
end;
关于网络的进一步调查,我在使用Microsoft推荐的技术的PrintBitmap程序中积累了一些建议。
我用PrintBitmap调用替换了所有Canvas.draw调用(假设在调用之外设置begindoc和enddoc)。
作为周末,我不能在办公室的问题打印机上测试它,但它至少不会破坏家用HP Deskjet打印机上的打印(无论如何都可以使用这两种方法)。
procedure PrintBitmap(X,Y:integer; Abmp:Tbitmap);
var Info: PBitmapInfo;
InfoSize,ImageSize: DWORD; Image: Pointer;
DIBWidth, DIBHeight: LongInt;
begin
with Printer do
begin
GetDIBSizes(Abmp.Handle, InfoSize, ImageSize);
Info := AllocMem(InfoSize);
Image := AllocMem(ImageSize);
try
GetDIB(Abmp.Handle, 0, Info^, Image^);
with Info^.bmiHeader do
begin
DIBWidth := biWidth;
DIBHeight := biHeight;
end;
StretchDIBits(Canvas.Handle, X, Y, DIBWidth, DIBHeight, 0, 0,
DIBWidth, DIBHeight, Image, Info^, DIB_RGB_COLORS, SRCCOPY);
finally
FreeMem(Image, ImageSize);
FreeMem(Info, InfoSize);
end
end;
end;