4

よろしくお願いします!

TPrinter で Delphi の写真を実際のサイズの写真で印刷するにはどうすればよいですか? TImage のキャンバスからは良い結果が得られますが、TPrinter キャンバスにペイントすると悪い結果が得られます。

なぜそれが起こるのですか? バグを修正するために何をする必要がありますか?

アップデート

はい、最初の投稿のヒントから質問を見ました。プロジェクトで JCL/JVCL コードを使用できませんが、そこからアイデアを得ました。

一時的な TImage を作成し、プリンターの DPI の係数に従ってその寸法を計算します。

var
  i, iRow, iCol,        // Counter
  iBorderSize,          // Ident from left/top borders
  iImgDistance,         // Ident between images in grid
  iRows,                // Rows Count
  iColumns,             // Colun count
  iLeft, iTop: Integer; // For calc
  bmp: TBitmap;
  bStop, bRowDone, bColDone: Boolean;
  Img1: TImage;
  scale: Double;

  function CalcY: Integer;
  begin
    if (iRow = 1) then
      Result := iBorderSize
    else
      Result := iBorderSize + (iImgDistance * (iRow - 1)) +
        (bmp.Height * (iRow - 1));
  end;

  function CalcX: Integer;
  begin
    if (iCol = 1) then
      Result := iBorderSize
    else
      Result := iBorderSize + (iImgDistance * (iCol - 1)) +
        (bmp.Width * (iCol - 1));
  end;

begin
  iBorderSize := StrToInt(BorderSizeEdit.Text);
  iImgDistance := StrToInt(ImgsDistanceEdit.Text);
  iRows := StrToInt(RowsCountEdit.Text);
  iColumns := StrToInt(ColCountEdit.Text);
  iRow := 1;
  iCol := 1;
  iLeft := iBorderSize;
  iTop := iBorderSize;

  if Printer.Orientation = poPortrait then
    scale := GetDeviceCaps(Printer.Handle, LOGPIXELSX) /
      Screen.PixelsPerInch
  else
    scale := GetDeviceCaps(Printer.Handle, LOGPIXELSY) /
      Screen.PixelsPerInch;

  bmp := TBitmap.Create;
  Img1 := TImage.Create(nil);
  Img1.Height := Trunc(Printer.PageHeight / scale); //Calc canvas size
  Img1.Width := Trunc(Printer.PageWidth / scale); //Calc canvas size
  Img1.Canvas.Brush.Color := clWhite;
  Img1.Canvas.FillRect(Rect(0, 0, Img1.Width, Img1.Height));
  try
    bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Source.bmp');
    for i := 1 to 18 do
    begin
      if (iRow <= iRows) then
      begin
        iTop := CalcY;
        iLeft := CalcX;
        Img1.Canvas.Draw(iLeft, iTop, bmp);
        if not((iRow = iRows) and (iCol = iColumns)) then
        begin
          if (iCol = iColumns) then
          begin
            Inc(iRow);
            iCol := 1;
          end
          else
            Inc(iCol);
        end
        else
        begin
          PrintImage(Img1, 100);
          iRow := 1;
          iCol := 1;
          Img1.Canvas.Brush.Color := clWhite;
          Img1.Canvas.FillRect(Rect(0, 0, Img1.Width, Img1.Height));
        end;
      end;
    end;
  finally
    FreeAndNil(bmp);
    FreeAndNil(Img1);
  end;
end;

そして、TPrinter.Canvas に描画します。

以下の結果を確認できます。

以下の結果を確認できます。

結果は良好ですが、完璧ではありません。

ご覧のとおり、最後の列では、すべての画像が最後まで描かれておらず、紙からはみ出して描かれていない部分もあります。

TImage.Canvas の寸法をプリンターの DPI の係数に従って計算するときに、Trunc を使用して double の整数部分を取得するために発生したと思います。

実験によって、私は値 0.20 を知っています。0.20 は、描画されていない最後の列の画像 (ピクセル単位) の一部です。コードを変更すると、次のようにスケール ファクターが取得されます。

  if Printer.Orientation = poPortrait then
    scale := GetDeviceCaps(Printer.Handle, LOGPIXELSX) /
      Screen.PixelsPerInch - 0.20
  else
    scale := GetDeviceCaps(Printer.Handle, LOGPIXELSY) /
      Screen.PixelsPerInch - 0.20;

私はそれを持っています、私が必要とするもの:

私はそれを持っています、私が必要とするもの:

値 0.20 は定数ではなく、すべての PC で変化すると思います。この値を計算する方法は?この問題を解決するには何が必要ですか?

4

3 に答える 3

1

あなたが直面している問題は、実際には画像の「実際のサイズ」がなく、すべて相対的だということです。多くの場合、プリンターの解像度はモニターよりもはるかに高いため、画像が小さく見えます。

多くの場合、モニターの解像度は 96 dpi で、通常のプリンターの解像度は 600 dpi です。これは、プリンターがモニターよりも多くのドットを同じスペースに配置できるため、画像が実際のサイズで印刷され、小さく見えることを意味します。

于 2013-08-02T07:03:42.200 に答える
1

Delphi Basics のリンクも役に立ちました: http://www.delphibasics.co.uk/RTL.asp?Name=printer&ExpandCode1=Yes

フォーム上: ツール パレットから TPrintDialog をドラッグ アンド ドロップします。

これを [Implementation] の下の uses 句に手動で追加します。

uses printers;  // Unit containing the printer command

それとこの投稿で、画像やテキストに必要なサイズで任意のプリンターに直接印刷することができました. 上記のユニットを追加したら、ビットマップを呼び出したり、TPrinter を割り当てたりする必要はありません。PC のプリンター キューのキャンバスに直接描画するだけです。

procedure TForm1.cmdPrintCircleClick(Sender: TObject);
 var
   xx, yy, mySize : integer;
   //printer1 : TPrinter;
 begin
  // create image directly on Printer Canvas and print it
  //Ellipse( X-(Width div 2), Y-(Height div 2), X+(Width div 2), Y+(Height div 2));
  if PrintDialog1.Execute then
   try
    with Printer do
     begin
      if Printer.Orientation = poPortrait then
       begin
         // represents 1/2 US-inch relative to Portrait page size 8.5 x 11
         mySize := Trunc(PageWidth / 8.5 / 2);
      end
      else
       begin
         // represents 1/2 US-inch relative to Landscape page size 11 x 8.5
         mySize := Trunc(PageHeight / 8.5 / 2);
      end;

      xx := Trunc(PageWidth / 2);
      yy := Trunc(PageHeight / 2);

      // Start printing
      BeginDoc;

      // Write out the ellipse  // create one-inch black circle
      Canvas.Brush.Color := clBlack;
      Canvas.Ellipse(xx - mySize, yy - mySize, xx + mySize, yy + mySize);

      // Finish printing
      EndDoc;
    end;
   finally
   end;

end;
于 2016-06-01T20:24:19.043 に答える