1

Bitmap image height may be greater than page height. In this case it should printed into multiple pages.

I tried code below for small single page image but got OutOfMemoryException at line

    e.Graphics.DrawImage(bm.Clone(new Rectangle(0, 
       pageHeight * (pageno - 1), bm.Width, 
       pageHeight),
        System.Drawing.Imaging.PixelFormat.DontCare),
        0, 0);

Printing is done in ASP.NET MVC4 controller to server printer using

using System.Drawing.Printing;
using System.Drawing;
using System.IO;


        byte[] bmp =   bmp image created by wkhtmltoimage
        var doc = new PrintDocument();
        doc.PrinterSettings.PrinterName = "myprinter";
        doc.PrintPage += new PrintPageEventHandler(ProvideContent);
        pageHeight = doc.DefaultPageSettings.PaperSize.Height;
        using (bm = new Bitmap(new MemoryStream(bmp)))
        {
            var lehti = (int)Math.Ceiling((double)(bm.Height / pageHeight));
            doc.PrinterSettings.FromPage = 1;
            doc.PrinterSettings.ToPage = lehti;
            doc.PrinterSettings.MaximumPage = 1;
            doc.PrinterSettings.MinimumPage = lehti;
            pageno = 1;
            doc.Print();
        }
    }

    int pageno;
    int pageHeight;
    Bitmap bm;

    void ProvideContent(object sender, PrintPageEventArgs e)
    {
        e.Graphics.DrawImage(bm.Clone(new Rectangle(0, pageHeight * (pageno - 1), bm.Width, pageHeight), System.Drawing.Imaging.PixelFormat.DontCare),
            0, 0);
    }

How to print image to multiple pages ? e.Graphics.DrawImage(bm,0, 0); works but only top part of image is printed.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
Andrus
  • 26,339
  • 60
  • 204
  • 378
  • 1
    Without [a good, _minimal_, _complete_ code example](http://stackoverflow.com/help/mcve) that shows clearly what you've tried, with a precise explanation of what that code does and how that's different from what you want, it's not possible to answer. **Generally though:** you need to "paginate" yourself. There's no reason to close the bitmap; just use the page dimensions and its own to calculate how many page rectangles are needed to cover the whole bitmap, then keep printing pages in sequence until you have drawn each of those bitmap subsets to a page. – Peter Duniho Nov 12 '15 at 17:06
  • 1
    You may want to look at the article here: http://www.codeproject.com/Articles/339416/Printing-large-WPF-UserControls. It is for WPF, but it describes the basic algorithm for paginating a bitmap and so may be useful to you. I am editing your tags, as this question does not appear to have anything at all to do with ASP.NET per se. – Peter Duniho Nov 12 '15 at 17:08
  • Thank you for good link. Good article and nice page break search code. I'ts bad that it uses unsafe code. Maybe it can changed to use safe code only. You can wrote it as answer and I can accept it. I solved Out of memory issue using DrawImage code from accepted answer from http://stackoverflow.com/questions/734930/how-to-crop-an-image-using-c – Andrus Nov 12 '15 at 19:09
  • The linked article uses `unsafe` only for direct access to the bitmap pixel data, because of the way they are paginating. In your case, the calculation of the pagination breaks should be much simpler: just break at the boundaries of the printable area of the page. You can just ignore the `while` loop where `IsRowGoodBreakingPoint()` is called; just set `pageBreak` equal to `pageHeight` and print the page (similar for the width, if necessary...the vertical page break will just occur at the page width). – Peter Duniho Nov 12 '15 at 22:33
  • I'm currenty using fixed page height. Last line in end of page is unreadable: part of it appears in end of page and part of it at start of next page. How to fix this without using unsafe code ? – Andrus Nov 13 '15 at 19:49
  • Sorry...it wasn't clear to me from your question that you had the same text-detection goal as in that related article. I guess it was even more relevant than I'd realized. :) Anyway, that article was for WPF and was going even beyond the normal optimizations for fast access to bitmap data. Unsafe code is a means to that end, but is not strictly required to accomplish the same thing. – Peter Duniho Nov 13 '15 at 20:06
  • You can achieve similar performance by using arrays and `Bitmap.LockBits()`; you'll need to use the `Marshal.Copy()` method to move the data from the unmanaged `Scan0` buffer to your own managed `byte[]` for processing, but that will actually not add too much overhead. You should still get adequate performance, no unsafe code required. – Peter Duniho Nov 13 '15 at 20:06
  • In Linux output is zoomed and unsharp. I posted it as separate question in http://stackoverflow.com/questions/33711676/how-to-print-bitmap-without-zoom-from-mvc-controller-in-linux-server . This contains also code example which you required in first comment. – Andrus Nov 14 '15 at 18:16
  • @PeterDuniho . I posted also related question about pdf printing which can also solve the issue in http://stackoverflow.com/questions/33712356/how-to-print-pdf-in-debian-linux-from-mvc-controller – Andrus Nov 14 '15 at 19:23

0 Answers0