web-dev-qa-db-ja.com

PrintDocumentを使用した画像の印刷。用紙サイズに合わせて画像を調整する方法

C#では、PrintDocumentクラスと以下のコードを使用して画像を印刷しようとしています。画像のサイズは幅1200ピクセル、高さ1800ピクセルです。小さなZeebraプリンターを使用して、この画像を4 * 6用紙に印刷しようとしています。しかし、プログラムは、大きな画像の4 * 6だけを印刷しています。これは、画像を用紙サイズに調整していないことを意味します!

     PrintDocument pd = new PrintDocument();
     pd.PrintPage += (sender, args) =>
     {
           Image i = Image.FromFile("C://tesimage.PNG");
           Point p = new Point(100, 100);
           args.Graphics.DrawImage(i, 10, 10, i.Width, i.Height);
     };
     pd.Print();

Window Printを使用して同じ画像を印刷する場合(右クリックして[印刷]を選択すると、用紙サイズに合わせて自動的にスケーリングされ、正しく印刷されます。つまり、すべてが4 * 6用紙になります)

29
Happy

DrawImageメソッドに渡すパラメーターは、画像自体のサイズではなく、用紙上の画像のサイズにする必要があります。DrawImageコマンドがスケーリングを処理します。おそらく最も簡単な方法は、DrawImageコマンドの次のオーバーライドを使用することです。

args.Graphics.DrawImage(i, args.MarginBounds);

注:画像の縦横比が長方形と同じでない場合、これにより画像が傾斜します。画像のサイズと用紙サイズに関する簡単な計算により、画像をゆがめることなく用紙の境界に収まる新しい長方形を作成できます。

33
BBoy

BBoyの既に適切な答えを踏みにじることはありませんが、アスペクト比を維持するコードを作成しました。私は彼の提案を受け入れたので、彼はここで部分的な信用を得なければなりません!

PrintDocument pd = new PrintDocument();
pd.DefaultPageSettings.PrinterSettings.PrinterName = "Printer Name";
pd.DefaultPageSettings.Landscape = true; //or false!
pd.PrintPage += (sender, args) =>
{
    Image i = Image.FromFile(@"C:\...\...\image.jpg");
    Rectangle m = args.MarginBounds;

    if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
    {
        m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
    }
    else
    {
        m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
    }
    args.Graphics.DrawImage(i, m);
};
pd.Print();
24
psyklopz

BBoyが提供するソリューションは正常に機能します。しかし、私の場合、私は使用しなければなりませんでした

e.Graphics.DrawImage(memoryImage, e.PageBounds);

これにより、フォームのみが印刷されます。 MarginBoundsを使用すると、フォームがモニター画面よりも小さい場合でも画面全体が印刷されます。 PageBoundsはその問題を解決しました。 BBoyに感謝します!

6
TonyM

ここで私のコードを使用できます

//Print Button Event Handeler
private void btnPrint_Click(object sender, EventArgs e)
{
    PrintDocument pd = new PrintDocument();
    pd.PrintPage += PrintPage;
    //here to select the printer attached to user PC
    PrintDialog printDialog1 = new PrintDialog();
    printDialog1.Document = pd;
    DialogResult result = printDialog1.ShowDialog();
    if (result == DialogResult.OK)
    {
        pd.Print();//this will trigger the Print Event handeler PrintPage
    }
}

//The Print Event handeler
private void PrintPage(object o, PrintPageEventArgs e)
{
    try
    {
        if (File.Exists(this.ImagePath))
        {
            //Load the image from the file
            System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\myimage.jpg");

            //Adjust the size of the image to the page to print the full image without loosing any part of it
            Rectangle m = e.MarginBounds;

            if ((double)img.Width / (double)img.Height > (double)m.Width / (double)m.Height) // image is wider
            {
                m.Height = (int)((double)img.Height / (double)img.Width * (double)m.Width);
            }
            else
            {
                m.Width = (int)((double)img.Width / (double)img.Height * (double)m.Height);
            }
            e.Graphics.DrawImage(img, m);
        }
    }
    catch (Exception)
    {

    }
}
4
Anas Naguib

回答:

public void Print(string FileName)
{
    StringBuilder logMessage = new StringBuilder();
    logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ START - {0} - {1} -------------------]", MethodBase.GetCurrentMethod(), DateTime.Now.ToShortDateString()));
    logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "Parameter: 1: [Name - {0}, Value - {1}", "None]", Convert.ToString("")));

    try
    {
        if (string.IsNullOrWhiteSpace(FileName)) return; // Prevents execution of below statements if filename is not selected.

        PrintDocument pd = new PrintDocument();

        //Disable the printing document pop-up dialog shown during printing.
        PrintController printController = new StandardPrintController();
        pd.PrintController = printController;

        //For testing only: Hardcoded set paper size to particular paper.
        //pd.PrinterSettings.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);
        //pd.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);

        pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
        pd.PrinterSettings.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);

        pd.PrintPage += (sndr, args) =>
        {
            System.Drawing.Image i = System.Drawing.Image.FromFile(FileName);

            //Adjust the size of the image to the page to print the full image without loosing any part of the image.
            System.Drawing.Rectangle m = args.MarginBounds;

            //Logic below maintains Aspect Ratio.
            if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
            {
                m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
            }
            else
            {
                m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
            }
            //Calculating optimal orientation.
            pd.DefaultPageSettings.Landscape = m.Width > m.Height;
            //Putting image in center of page.
            m.Y = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Height - m.Height) / 2);
            m.X = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Width - m.Width) / 2);
            args.Graphics.DrawImage(i, m);
        };
        pd.Print();
    }
    catch (Exception ex)
    {
        log.ErrorFormat("Error : {0}\n By : {1}-{2}", ex.ToString(), this.GetType(), MethodBase.GetCurrentMethod().Name);
    }
    finally
    {
        logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ END  - {0} - {1} -------------------]", MethodBase.GetCurrentMethod().Name, DateTime.Now.ToShortDateString()));
        log.Info(logMessage.ToString());
    }
}
4
KhanSahib

TonyMとBBoyに同意する-これは、ラベルの元の4 * 6印刷の正解です。 (args.PageBounds)。これは、Endicia APIサービス出荷ラベルの印刷に役立ちました。

private void SubmitResponseToPrinter(ILabelRequestResponse response)
    {
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += (sender, args) =>
        {
            Image i = Image.FromFile(response.Labels[0].FullPathFileName.Trim());
            args.Graphics.DrawImage(i, args.PageBounds);
        };
        pd.Print();
    }
4
user1807576