有没有可靠的方法在Tprinter画布上绘制位图?

时间:2013-03-08 10:27:16

标签: delphi delphi-2007

我创建了一个打印预览对象,允许我将来自不同来源的多个图形对象组织到打印页面上。

为了在打印机画布上渲染这些对象,我必须首先将它们渲染为计算大小的位图,然后使用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;

0 个答案:

没有答案