I've been working on a project recently that had a requirement to do a tiff to pdf conversion on the fly, and serve these pdf's over the web. The added wrinkle was that these tiff files were stored in a database - so I wasn't going to reading or writing from the filesystem. This isn't a huge problem, but it did throw 90% of the examples out of the window!
I opted to use PdfSharp to do the conversion this - it's a really great open source library and did exactly what I needed.
So here we go:
snippet 1:
byte[] bytes = GetMyByteData(); using (MemoryStream memoryStream = new MemoryStream(bytes)) { memoryStream.Position = 0; memoryStream.Write(bytes, 0, bytes.Length); System.Drawing.Image image = System.Drawing.Image.FromStream(memoryStream, true, true); //This is where the next code goes!! }
To start with I retrieved my data from the database into a byte array, wrote it into a memory stream object and finally created an Image object from the memory stream. Next onto creating the pdf document:
snippet 2:
PdfDocument doc = new PdfDocument(); XGraphics xgr; PdfPage page = new PdfPage(); doc.Pages.Add(page); xgr = XGraphics.FromPdfPage(page); XImage ximg = XImage.FromGdiPlusImage(image); xgr.DrawImage(ximg, 0, 0);
As you can see from the code, this is where PdfSharp comes into play (I opted for the GDI+ version) - creating a PdfDocument, XGraphics object, PdfPage and loading the image into page. I guess the real magic here when using the XImage.FromGdiPlusImage method to load the in memory image file into a pdf writeable object.
Finally was writing this back to the response stream (in ASP.NET obviously!):
snippet 3:
using (MemoryStream responseStream = new MemoryStream()) { doc.Save(responseStream, false); responseStream.Position = 0; context.Response.ClearContent(); context.Response.ClearHeaders(); context.Response.BufferOutput = true; context.Response.ContentType = "application/pdf"; context.Response.AddHeader("content-disposition", "inline;filename=mypdf.pdf"); responseStream.CopyTo(context.Response.OutputStream); context.Response.Flush(); context.Response.Close(); context.Response.End(); } doc.Close();
I wont go into too much detail about this, its pretty straight forward stuff. For me the 2 things really worth mentioning is the doc.Save() method which saves the pdf to a new memory stream, and the responseStream.CopyTo method which copies one stream to another (new to .net 4 I think!).
This all worked fine but there was one further complication - the TIFFs might be multi-page. In those examples the pdf would only ever contain the first page. To overcome this I had to loop over the page frames and add a new pdf page for each one. This replaces snippet 2 with the following:
snippet 2(v2):
PdfDocument doc = new PdfDocument(); XGraphics xgr; int count = image.GetFrameCount(FrameDimension.Page); for (int pageNum = 0; pageNum < count; pageNum++) { image.SelectActiveFrame(FrameDimension.Page, pageNum); PdfPage page = new PdfPage(); doc.Pages.Add(page); xgr = XGraphics.FromPdfPage(page); XImage ximg = XImage.FromGdiPlusImage(image); xgr.DrawImage(ximg, 0, 0); }
I was pleasantly surprised with how straight forward this was to achieve, and in particular how quickly it all worked.
Matt
source : http://www.codenutz.com/2011/10/creating-multi-page-pdf-from-tiff-tiff.html