Delphi 如何打印大于一页的图像

Delphi 如何打印大于一页的图像,delphi,canvas,printing,delphi-10.3-rio,Delphi,Canvas,Printing,Delphi 10.3 Rio,我需要打印从扫描仪获取的图像。 当扫描适合一张A4纸时,就没有问题了,我的代码打印得非常完美 但是,如果扫描不适合,但需要2页,则只打印一页。第一个 这是到目前为止我的代码 procedure TFormMain.PrintPicture; var MyRect: TRect; Scale: Double; begin try Printer.BeginDoc; Scale := Printer.PageWidth / ImgHolder.Picture.Bitma

我需要打印从扫描仪获取的图像。
当扫描适合一张A4纸时,就没有问题了,我的代码打印得非常完美

但是,如果扫描不适合,但需要2页,则只打印一页。第一个

这是到目前为止我的代码

procedure TFormMain.PrintPicture;
var
  MyRect: TRect;
  Scale: Double;
begin
  try
    Printer.BeginDoc;

    Scale := Printer.PageWidth / ImgHolder.Picture.Bitmap.Width;
    MyRect.Left := 0;
    MyRect.Top := 0;
    MyRect.Right := trunc(ImgHolder.Picture.Bitmap.Width * Scale);
    MyRect.Bottom := trunc(ImgHolder.Picture.Bitmap.Height * Scale);
    Printer.Canvas.StretchDraw(MyRect, ImgHolder.Picture.Bitmap);

    Printer.EndDoc;
  except
    on E:Exception do
    begin
      MessageBox(Handle, PChar('Printing failed' + chr(13) + E.Message), PChar(Caption), MB_OK or MB_ICONWARNING);
    end;
  end;
end;
当图像包含一页时,
MyRect
=13092
当图像包含2页时,高度为26185

这对我来说似乎是正确的,但仍然只打印了第一页。 所以我一定是做错了,有人能告诉我如何打印一张比一页高的图片吗

编辑
如果图像较大,我想在多个页面上打印。
我不想将图像缩小到一页。
在我的代码中使用比例的原因是,我一开始无法正确打印,我在另一个问题中找到了这段代码,为我解决了这个问题。
但现在看来这种方法是错误的。
因此,如果我能得到一些帮助来设置正确的打印方式,我将不胜感激

如果用户扫描2或3次,图像将变大,新扫描将添加到底部的图像中。
这就是图像超过一页的原因。

现在我需要完整地打印此图像,因此如果需要在多个页面上打印

要在多个页面上打印大图像,您必须在宽度和高度上循环(两个循环)以创建包含部分图像的页面。要打印一张局部图像,可以使用

打印图像的方法有很多种

首先,请记住,您的屏幕和打印机有不同的分辨率(比如每英寸像素数)。通常,打印机的分辨率比PC显示器高得多,因此,如果在A4页面上打印1920×1080的全屏图像,除非将其放大,否则页面上将显示非常小的图像

现在,让我们考虑两个常见的场景(你想要第二个场景)。

缩放图像,使其完全适合单个页面 我所说的“完美匹配”,是指图像按比例缩放,保留其纵横比,以便在页面上尽可能大而不被剪裁

Let(
使用数学

ScaleX:=Printer.PageWidth/Bitmap.Width;
ScaleY:=Printer.PageHeight/Bitmap.Height;
比例:=最小值(比例X、比例Y)。
然后,
Scale
是您的比例因子

事实上,
ScaleX
是最大的缩放因子,允许图像水平地适合页面。例如,如果纸张为1000×1000,图像为2000×1000,则显然需要将其缩小到至少
ScaleX=50%
,以使其水平适合。另一方面,如果图像是1000×5000,问题不在于宽度而是高度,显然需要将其缩小到至少
ScaleY=20%
,使其垂直适合


因此,如果图像是2000×5000,则需要将比例因子设置为50%或更小,以使其水平适合,并且需要将比例因子设置为20%或更小,以使其垂直适合。满足这两个限制的最大比例系数为20%,最小比例系数为50%和20%

程序打印位图(ABitmap:TBitmap);
开始
Printer.BeginDoc;
var ScaleX:=Printer.PageWidth/ABitmap.Width;
变量ScaleY:=Printer.PageHeight/ABitmap.Height;
变量比例:=最小值(ScaleX,ScaleY);
变量W:=圆形(绝对贴图宽度*刻度);//注:按比例缩放,
变量H:=圆形(绝对高度*刻度);//相同因素
Printer.Canvas.Brush.Color:=clRed;
Printer.Canvas.StretchDraw(
TRect.Create(//在第页居中
点((Printer.PageWidth-W)第2部分,(Printer.PageHeight-H)第2部分),
W、 H
),
ABitmap
);
Printer.EndDoc;
结束;
比如说,

过程TForm1.FormCreate(发送方:TObject);
开始
var bm:=TBitmap.Create;
尝试
LoadFromFile('K:\Sally.bmp');
打印位图(bm);
最后
bm.Free;
结束;
结束;

具有固定的图像大小,可能跨越多个页面 现在,假设您有一个固定的图像大小
(W,H)
,并且希望根据需要在任意多的页面上打印它。然后,需要在二维图纸网格中循环并分别绘制每页:

程序打印位图(ABitmap:TBitmap);
变量
W、 H:整数;
ImgPageWidth、ImgPageHeight:整数;
函数GetSourceRect(行、列:整数):TRect;
开始
结果:=TRect.Create(
点(列*ImgPageWidth,行*ImgPageHeight),
ImgPageWidth,ImgPageHeight
);
结束;
函数GetDestRect(行、列:整数):TRect;
开始
结果:=Rect(0,0,Printer.PageWidth,Printer.PageHeight);
结束;
开始
Printer.BeginDoc;
W:=绝对贴图宽度*4;//在本例中,对这些进行硬编码
H:=ABitmap.高度*4;
ImgPageWidth:=圆形(ABitmap.Width*(Printer.PageWidth/W));
ImgPageHeight:=圆形(ABitmap.Height*(Printer.PageHeight/H));
var PageCountX:=Ceil(带打印机.PageWidth);//页面中的图像宽度
var PageCountY:=Ceil(H/Printer.PageHeight);//页面中的图像高度
//请注意,总页数是PageCountX*PageCountY。
对于变量y:=0到PageCountY-1 do
对于变量x:=0到PageCountX-1 do
开始
如果x+y>0,则
Printer.NewPage;
Printer.Canvas.CopyRect(
GetDestRect(y,x),
ABitmap画布,
GetSourceRect(y,x)
);
结束;
Printer.EndDoc;
结束;


您应该根据高度和宽度计算两个比例因子,并使用这两个因子中最严格的一个。@fpiette需要多一点explanation@GuidoG:
ScaleX:=Printer.PageWidth/ImgHolder.Picture.Bitmap.Width;ScaleY:=Printer.PageHeight/ImgHolder.Picture.Bitmap.Height;比例:=Min(ScaleX,ScaleY)
使用数学
)。或者,换句话说:
ScaleX
是收缩的fac