2

1 つの縦長の画像を複数のページに印刷したい。そのため、すべてのページで、画像から適切な部分を取り出してページに描画します。

問題は、ページ内の画像が縮小されている (形状が圧縮されている) ため、その値が 1500 であるスケールを追加したことです。ページ(e.Graphics)の高さがピクセル単位で分かれば解けると思います。インチをピクセルに変換するには、 (e.Graphics.DpiX = 600) を掛けるか、 96 を掛ける必要がありますか?

void printdocument_PrintPage(object sender, PrintPageEventArgs e)
        {
           if (pageImage ==  null) 
               return;
            e.Graphics.PageUnit = GraphicsUnit.Pixel;

            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;


            float a = (e.MarginBounds.Width / 100) * e.Graphics.DpiX;
            float b = ((e.MarginBounds.Height / 100) * e.Graphics.DpiY);
            int scale = 1500;
            scale = 0; //try to comment this
            RectangleF srcRect = new RectangleF(0, startY, pageImage.Width, b - scale);
            RectangleF destRect = new RectangleF(0, 0, a, b);
            e.Graphics.DrawImage(pageImage, destRect, srcRect, GraphicsUnit.Pixel);
            startY = Convert.ToInt32(startY + b - scale);
            e.HasMorePages = (startY < pageImage.Height);
        }

正しく動作するようにしてください。

ソースコードは (ここ)からダウンロードできます。

ありがとうございます。

4

2 に答える 2

2

私はあなたの仕事を完了しようとしました。どうぞ。それが役に立てば幸い。

このメソッドは、イメージを複数のページ (イメージが小さい場合は 1 ページ) に印刷します。

private void printImage_Btn_Click(object sender, EventArgs e)
    {
        list = new List<Image>();
        Graphics g = Graphics.FromImage(image_PctrBx.Image);
        Brush redBrush = new SolidBrush(Color.Red);
        Pen pen = new Pen(redBrush, 3);
       decimal xdivider = image_PctrBx.Image.Width / 595m;
        int xdiv = Convert.ToInt32(Math.Ceiling(xdivider));
        decimal ydivider = image_PctrBx.Image.Height / 841m;
        int ydiv = Convert.ToInt32(Math.Ceiling(ydivider));
        /*int xdiv = image_PctrBx.Image.Width / 595; //This is the xsize in pt (A4)
        int ydiv = image_PctrBx.Image.Height / 841; //This is the ysize in pt (A4)
        // @ 72 dots-per-inch - taken from Adobe Illustrator

        if (xdiv >= 1 && ydiv >= 1)
        {*/
            for (int i = 0; i < xdiv; i++)
            {
                for (int y = 0; y < ydiv; y++)
                {
                    Rectangle r;
                    try
                    {
                        r = new Rectangle(i * Convert.ToInt32(image_PctrBx.Image.Width / xdiv),
                                                    y * Convert.ToInt32(image_PctrBx.Image.Height / ydiv),
                                                    image_PctrBx.Image.Width / xdiv,
                                                    image_PctrBx.Image.Height / ydiv);
                    }
                    catch (Exception)
                    {
                        r = new Rectangle(i * Convert.ToInt32(image_PctrBx.Image.Width / xdiv),
                          y * Convert.ToInt32(image_PctrBx.Image.Height),
                          image_PctrBx.Image.Width / xdiv,
                          image_PctrBx.Image.Height);
                    }


                    g.DrawRectangle(pen, r);
                    list.Add(cropImage(image_PctrBx.Image, r));
                }
            }

        g.Dispose();
        image_PctrBx.Invalidate();
        image_PctrBx.Image = list[0];

        PrintDocument printDocument = new PrintDocument();
        printDocument.PrintPage += PrintDocument_PrintPage;
        PrintPreviewDialog previewDialog = new PrintPreviewDialog();
        previewDialog.Document = printDocument;
        pageIndex = 0;
        previewDialog.ShowDialog();
        // don't forget to detach the event handler when you are done
        printDocument.PrintPage -= PrintDocument_PrintPage;
    }

このメソッドは、リスト内のすべての画像を必要な寸法 (A4 サイズ) で印刷します。

        private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
    {
        // Draw the image for the current page index
        e.Graphics.DrawImageUnscaled(list[pageIndex],
                                     e.PageBounds.X,
                                     e.PageBounds.Y);
        // increment page index
        pageIndex++;
        // indicate whether there are more pages or not
        e.HasMorePages = (pageIndex < list.Count);
    }

このメソッドは画像をトリミングし、画像のすべての部分を返します。

    private static Image cropImage(Image img, Rectangle cropArea)
    {
        Bitmap bmpImage = new Bitmap(img);
        Bitmap bmpCrop = bmpImage.Clone(cropArea, System.Drawing.Imaging.PixelFormat.DontCare);
        return (Image)(bmpCrop);
    }

画像は PictureBox から読み込まれるため、画像が読み込まれていることを確認してください。(まだ例外処理はありません)。

    internal string tempPath { get; set; }
    private int pageIndex = 0;
    internal List<Image> list { get; set; }

これらの変数はグローバル変数として定義されています。

ここからサンプル プロジェクトをダウンロードできます。

http://www.abouchleih.de/projects/PrintImage_multiplePages.zip // 古いバージョン http://www.abouchleih.de/projects/PrintImage_multiplePages_v2.zip // 新しい

于 2012-12-28T23:36:32.077 に答える