How to use this with FJCore Library.

Jan 12, 2011 at 4:35 AM

As the PNG's generated are huge and my requirement for printing is to print a bigger panel which spans across multiple pages, i started exploring several other options running around the same concept. Fortunately i found a way to address the issues with huge PNG's.

//In Silverlight App

 WriteableBitmap bitmap = new WriteableBitmap(pnlMain, null);

                //bitmap.
                //TestImage.Source
                //return;
                // Save it to disk
                //Get the stream from the encoder and create byte array from it
                //System.IO.Stream pngStream = imageData.GetStream();
                //bitmap.SetSource(pngStream);
                //TestImage.Source = bitmap;
                int width = bitmap.PixelWidth;
                int height = bitmap.PixelHeight;
                int bands = 3;
                byte[][,] raster = new byte[bands][,];

                //Convert the Image to pass into FJCore
                //Code From http://stackoverflow.com/questions/1139200/using-fjcore-to-encode-silverlight-writeablebitmap
                for (int i = 0; i < bands; i++)
                {
                    raster[i] = new byte[width, height];
                }

                for (int row = 0; row < height; row++)
                {
                    for (int column = 0; column < width; column++)
                    {
                        int pixel = bitmap.Pixels[width * row + column];
                        raster[0][column, row] = (byte)(pixel >> 16);
                        raster[1][column, row] = (byte)(pixel >> 8);
                        raster[2][column, row] = (byte)pixel;
                    }
                }

                //ColorModel model = new ColorModel { Opaque = true };
                ColorModel model = new ColorModel { colorspace = ColorSpace.RGB };
                //FluxJpeg.Core.Image img=new FluxJpeg.Core.Image(
                FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster);
                //TestImage.Source = img;
                //Encode the Image as a JPEG
                MemoryStream stream = new MemoryStream();
                FluxJpeg.Core.Encoder.JpegEncoder encoder = new FluxJpeg.Core.Encoder.JpegEncoder(img, 100, stream);
                encoder.Encode();

                //Back to the start
                stream.Seek(0, SeekOrigin.Begin);

                //Get teh Bytes and write them to the stream
                printBuffer = new Byte[stream.Length];
                long bytesRead = stream.Read(printBuffer, 0, (int)printBuffer.Length);
                //fs.Write(binaryData, 0, binaryData.Length);

                //printBuffer = new Byte[pngStream.Length];
                //pngStream.Read(printBuffer, 0, printBuffer.Length);

                switch (sfd.FilterIndex)
                {
                    case 1:
                        //HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(new Uri(Application.Current.Host.Source.ToString().Substring(0, Application.Current.Host.Source.ToString().LastIndexOf("/")) + "/Png2Pdf.ashx"));
                        HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(new Uri(BuildHostURI(App.Current.Host.Source) + "/Png2Pdf.ashx"));

                        hwr.Method = "POST";

                        printStream = sfd.OpenFile();
                        printSyncContext = System.Threading.SynchronizationContext.Current;
                        hwr.BeginGetRequestStream(new AsyncCallback(PrintStart), hwr);


                        break;
                    case 2:
                        //Save the PNG to local disk
                        System.IO.Stream fs = sfd.OpenFile();
                        fs.Write(printBuffer, 0, printBuffer.Length);
                        fs.Close();
                        Messenger.Default.Send<bool>(false, "ReportBusyIndicator");
                        MessageBox.Show("You JPEG has been created.", "Export Complete", MessageBoxButton.OK);
                        break;
                }

 

//In HTTP Handler

public class Png2Pdf : IHttpHandler
  {
    private int _BufferSize = 132768;
    private int _Margin = 54; // 3/4 inch margin
    //private int imageHeight = 700;
    //private int imageWidth = 480;

    public void ProcessRequest(HttpContext context)
    {
      if (context.Request.ContentLength > 0)
      {
        System.IO.Stream incomingStream = context.Request.InputStream;  //Get the incoming stream
        System.Drawing.Image img = System.Drawing.Image.FromStream(incomingStream); //Create and image from the stream

        
        int pageHeight = img.Height  + (_Margin * 2);
        int pageWidth = img.Width + (_Margin * 2);

        iTextSharp.text.Image pdfImage = iTextSharp.text.Image.GetInstance(img, System.Drawing.Imaging.ImageFormat.Jpeg);
        System.IO.MemoryStream pdfStream = new System.IO.MemoryStream();
        //iTextSharp.text.Font pdfFont = iTextSharp.text.Font.
        //iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(new iTextSharp.text.Rectangle(pageWidth, pageHeight));

        iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document();
        iTextSharp.text.pdf.PdfWriter pdfWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(pdfDoc, pdfStream);
        

        //Insure this is set otherwise when the close method is called on the iTextSharp.text.Document the memory stream
        //we are writting to will be closed
        pdfWriter.CloseStream = false;

        ArrayList arrList = pdfImage.Chunks;
        //Open PDF and add image to it
        pdfDoc.Open();
        int PrintPageHeight = 900;


        for (int i = 0; i <= img.Height; i = i + PrintPageHeight)
            {
                Rectangle rect = new Rectangle(0, i, img.Width, PrintPageHeight);

                Bitmap bitmap = new Bitmap(rect.Width, rect.Height);
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.DrawImage(img,new Rectangle(0,0,rect.Width,rect.Height),rect,GraphicsUnit.Pixel);
                    //g.DrawImage(img,new Rectangle(0,0,img.Width,700),);
                    g.Save();
                    iTextSharp.text.Rectangle rectPage = iTextSharp.text.PageSize.A4;
                    
                    pdfDoc.SetPageSize(rectPage);
                    
                    pdfDoc.NewPage();
                    iTextSharp.text.Image pdfImage1 = iTextSharp.text.Image.GetInstance(bitmap, System.Drawing.Imaging.ImageFormat.Png);
                    pdfImage1.ScaleAbsolute(iTextSharp.text.PageSize.A4.Width - 60, iTextSharp.text.PageSize.A4.Height-50);
                    pdfDoc.Add(pdfImage1);
                }
            }

            
        //pdfDoc.Add(pdfImage);
        //pdfDoc.Add(rcttest);
          //iTextSharp.text.Rectangle objRectangle=new iTextSharp.text.Rectangle((float)8.5,(float)10.5);
          //pdfDoc.SetPageSize(objRectangle);
              

        //Close the PDF document to commit the changes
        pdfDoc.Close();
        

        //Set response headers
        context.Response.Clear();
        context.Response.ContentType = "application/pdf";
        context.Response.AppendHeader("Content-Disposition", "attachment; filename=Export.pdf");
        context.Response.AppendHeader("Content-Length", pdfStream.Length.ToString());
        context.Response.Buffer = false;

        //Insure the stream is at the beginning
        if (pdfStream.Position > 0) { pdfStream.Position = 0; };

        //Stream the exported pdf to the client this is needed since the file size could be large in size
        Byte[] bytesRead = new Byte[_BufferSize];

        long toRead = pdfStream.Length; //Var used to determine how much to read

        while (toRead > 0 && context.Response.IsClientConnected)
        {
          //Insure that _BufferSize do not overrun the end of the stream
          if (_BufferSize > toRead)
          {
            _BufferSize = (int)toRead;
            bytesRead = new Byte[_BufferSize];
          };

          //Write pdf memory stream to bytesRead
          pdfStream.Read(bytesRead, 0, _BufferSize);

          //Read read bytes to outputStream
          context.Response.OutputStream.Write(bytesRead, 0, _BufferSize);

          //Flush response
          context.Response.Flush();

          //Create new byte array to store bytes to read
          bytesRead = new Byte[_BufferSize];

          //Update value used to check for end of stream
          toRead -= _BufferSize;
        }

        //Flush and close the stream
        context.Response.OutputStream.Flush();
        context.Response.End();

        //Close and displose of the memory stream
        if (pdfStream != null)
        {
          pdfStream.Close();
          pdfStream.Dispose();
        }
      }
    }

    public bool IsReusable
    {
      get
      {
        return false;
      }
    }
  }

This code fixes the issue of printing whole bigger page onto a single PDF page. This makes PDF with multiple pages.