Exemplo n.º 1
0
        /// <summary>
        /// Convert specified PDF file to Images (1 image per pdf page)
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        IEnumerable <Image> ExtractImages(string file)
        {
            Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;
            Ghostscript.NET.GhostscriptVersionInfo           vesion;
            vesion = new Ghostscript.NET.GhostscriptVersionInfo(new Version(0, 0, 0),
                                                                PathToDll + @"\gsdll32.dll",
                                                                string.Empty,
                                                                Ghostscript.NET.GhostscriptLicense.GPL);

            using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
            {
                try
                {
                    rasterizer.Open(file, vesion, false);
                    return(GetImagesFromRasterizer(rasterizer));
                }
                catch
                {
                    vesion = new Ghostscript.NET.GhostscriptVersionInfo(new Version(0, 0, 0),
                                                                        PathToDll + @"\gsdll64.dll",
                                                                        string.Empty,
                                                                        Ghostscript.NET.GhostscriptLicense.GPL);

                    rasterizer.Open(file, vesion, false);
                    return(GetImagesFromRasterizer(rasterizer));
                }
            }
        }
Exemplo n.º 2
0
        public static IList <byte[]> PDFToImage(MemoryStream ms, int ImgWidth, int ImgHeight)
        {
            string path = Path.GetDirectoryName(System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath);

            Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;
            Ghostscript.NET.GhostscriptVersionInfo           vesion     = new Ghostscript.NET.GhostscriptVersionInfo(new Version(0, 0, 0), @"C:\\Program Files\\gs\\gs9.19\\bin\\gsdll64.dll", string.Empty, Ghostscript.NET.GhostscriptLicense.GPL);
            IList <byte[]> images = new List <byte[]> ();

            using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
            {
                rasterizer.Open(ms, vesion, false);

                for (int i = 1; i <= rasterizer.PageCount; i++)
                {
                    MemoryStream returnImage = new MemoryStream();
                    Image        SrcImg      = rasterizer.GetPage(200, 200, i);
                    //if (SrcImg.Width <= ImgWidth) ImgWidth = SrcImg.Width;
                    //int NewHeight = SrcImg.Height * ImgWidth / SrcImg.Width;
                    //if (NewHeight > ImgHeight)
                    //{
                    //    // Resize with height instead
                    //    ImgWidth = SrcImg.Width * ImgHeight / SrcImg.Height;
                    //    NewHeight = ImgHeight;
                    //}

                    SrcImg.Save(returnImage, ImageFormat.Jpeg);
                    images.Add(returnImage.ToArray());
                }

                rasterizer.Close();
                return(images);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Get the images from PDF files in rasterizer
        /// </summary>
        /// <param name="rasterizer"></param>
        /// <returns></returns>
        IEnumerable <Image> GetImagesFromRasterizer(Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer)
        {
            var imagesList = new List <Image>();
            var task       = Task.Factory.StartNew(() => {
                for (int i = 1; i <= rasterizer.PageCount; i++)
                {
                    Image img = rasterizer.GetPage(300, 300, i);

                    EncoderParameter qualityParam =
                        new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 60L);

                    EncoderParameters encoderParams = new EncoderParameters
                    {
                        Param = new EncoderParameter[] { qualityParam }
                    };

                    var imageStream = new MemoryStream();
                    img.Save(imageStream, GetEncoderInfo("image/jpeg"), encoderParams);

                    Image imageExported = new Bitmap(imageStream);
                    if (NewSize != null)
                    {
                        imageExported = Util.ResizeImage(imageExported, NewSize);
                    }
                    imagesList.Add(imageExported);
                }
            });

            task.Wait();
            rasterizer.Close();
            return(imagesList);
        }
        protected List <string> PdfToImages(string file, string outputDir, int dpi)
        {
            try
            {
                List <string> fileNames = new List <string>();

                Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;

                string gsDllPath           = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Binaries\gsdll32.dll");
                GhostscriptVersionInfo gvi = new GhostscriptVersionInfo(gsDllPath);

                using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
                {
                    rasterizer.Open(file, gvi, true);

                    for (int i = 1; i <= rasterizer.PageCount; i++)
                    {
                        System.Drawing.Image img = rasterizer.GetPage(dpi, dpi, i);
                        string fileName          = Path.Combine(outputDir, string.Format("{0}.jpg", i));
                        img.Save(fileName, ImageFormat.Jpeg);
                        fileNames.Add(fileName);
                    }

                    rasterizer.Close();
                }

                return(fileNames);
            }
            catch (Exception ex)
            {
                //potentially log the exception
                throw;
            }
        }
Exemplo n.º 5
0
        public void PDFToImage(string file)
        {
            Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;

            using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
            {
                rasterizer.Open(file);

                for (int i = 1; i <= rasterizer.PageCount; i++)
                {
                    Image      img     = rasterizer.GetPage(300, 300, i);
                    Bitmap     bmp     = new Bitmap(img);
                    BitmapData bmpDate = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                    IntPtr     ptr     = bmpDate.Scan0;
                    int        bytes   = Math.Abs(bmpDate.Stride) * bmp.Height;
                    byte[]     rgbVal  = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbVal, 0, bytes);
                    bmp.UnlockBits(bmpDate);
                    Array byteArray = rgbVal;
                    OCR.Img_LoadBmpData(ImgObj, ref byteArray, bmp.Width, bmp.Height, TNSOCR.BMP_24BIT, 0);
                }

                rasterizer.Close();
            }
        }
        protected List<string> PdfToImages(string file, string outputDir, int dpi)
        {
            try
            {
                List<string> fileNames = new List<string>();

                Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;

                string gsDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Binaries\gsdll32.dll");
                GhostscriptVersionInfo gvi = new GhostscriptVersionInfo(gsDllPath);

                using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
                {
                    rasterizer.Open(file, gvi, true);

                    for (int i = 1; i <= rasterizer.PageCount; i++)
                    {
                        System.Drawing.Image img = rasterizer.GetPage(dpi, dpi, i);
                        string fileName = Path.Combine(outputDir, string.Format("{0}.jpg", i));
                        img.Save(fileName, ImageFormat.Jpeg);
                        fileNames.Add(fileName);
                    }

                    rasterizer.Close();
                }

                return fileNames;
            }
            catch (Exception ex)
            {
                //potentially log the exception
                throw;
            }
        }
Exemplo n.º 7
0
        private string ExtractUsingGhostScript(string pdfPath, string imagePath, int pageNo = 0)
        {
            using (var rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer()) {
                rasterizer.Open(pdfPath);
                imagePath = imagePath + ".png";

                var img = rasterizer.GetPage(300, 300, pageNo + 1);
                img.Save(imagePath, ImageFormat.Png);

                return(imagePath);
            }
        }
Exemplo n.º 8
0
        public static Dictionary<int, string> PDFToImage(string file, string outputPath, int dpi)
        {


            string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;
            Ghostscript.NET.GhostscriptVersionInfo vesion = new Ghostscript.NET.GhostscriptVersionInfo(new System.Version(0, 0, 0), path + @"\gsdll64.dll", string.Empty, Ghostscript.NET.GhostscriptLicense.GPL);

            Dictionary<int, string> dictionary = new Dictionary<int, string>();

            using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
            {
                rasterizer.Open(file, vesion, false);

                for (int i = 1; i <= rasterizer.PageCount; i++)
                {
                    string pageFilePath = Path.Combine(outputPath, Path.GetFileNameWithoutExtension(@file).Replace(".pdf", "") + "-p" + i.ToString() + ".tiff");

                    using (System.Drawing.Image img = rasterizer.GetPage(dpi, dpi, i))
                    {
                        
                            if (File.Exists(pageFilePath))
                            {
                              

                                //img.Save(pageFilePath, System.Drawing.Imaging.ImageFormat.Tiff);
                                dictionary.Add(i, pageFilePath);

                            }
                            else
                            {
                                img.Save(pageFilePath, System.Drawing.Imaging.ImageFormat.Tiff);
                                dictionary.Add(i, pageFilePath);
                                
                            }
                       
                            
                      
                    }
                    
                }
                rasterizer.Close();
                rasterizer.Dispose();

             
            }
            return dictionary;
        }
Exemplo n.º 9
0
 //Convert a pdf to a jpg image
 public void PDFToImage(string file, int dpi)
 {
     Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;
     using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
     {
         string pageFilePath = Path.Combine(Path.ChangeExtension(file, ".jpg"));
         if (File.Exists(pageFilePath))
             return;
         rasterizer.Open(file);
         for (int i = 1; i <= rasterizer.PageCount; i++)
         {
             using (System.Drawing.Image img = rasterizer.GetPage(dpi, dpi, i))
             {
                 img.Save(pageFilePath, ImageFormat.Jpeg);
             }
         }
         rasterizer.Close();
     }
 }
Exemplo n.º 10
0
        private void ExtractUsingGhostScript(Matrix coordinates)
        {
            float x = coordinates[Matrix.I31];
            float y = coordinates[Matrix.I32];
            float w = coordinates[Matrix.I11];
            float h = coordinates[Matrix.I22];

            using (var rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer()) {
                rasterizer.Open(currentPdfPath);

                var pageWidth  = pageSize.Width;
                var pageHeight = pageSize.Height;

                using (Bitmap img = (Bitmap)rasterizer.GetPage(120, 120, currentPage + 1)) {
                    int rectX = (int)(img.Width * x / pageWidth);
                    int rectY = (int)(img.Height * y / pageHeight);
                    int rectW = (int)(img.Width * w / pageWidth);
                    int rectH = (int)(img.Height * h / pageHeight);

                    RenderedImage = img.Clone(new System.Drawing.Rectangle(rectX, rectY, rectW, rectH), img.PixelFormat);
                }
            }
        }
Exemplo n.º 11
0
        static public List <string> PDFToImages(string file, string outputDirectory, int dpi, bool uniqueFileNames)
        {
            //string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            //path + @"\libs\gsdll32.dll"
            Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;
            Ghostscript.NET.GhostscriptVersionInfo           vesion     = new Ghostscript.NET.GhostscriptVersionInfo(new Version(0, 0, 0), HostingEnvironment.MapPath("~/Libs/gsdll32.dll"), string.Empty, Ghostscript.NET.GhostscriptLicense.GPL);
            List <string> outputFiles = new List <string>();

            using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
            {
                rasterizer.Open(file, vesion, false);

                for (int i = 1; i <= rasterizer.PageCount; i++)
                {
                    string pageFilePath = Path.Combine(outputDirectory, (uniqueFileNames ? Path.GetRandomFileName() : "") + Path.GetFileNameWithoutExtension(file) + "-p" + i.ToString() + ".jpg");
                    outputFiles.Add(pageFilePath);
                    Image img = rasterizer.GetPage(dpi, dpi, i);
                    img.Save(pageFilePath, ImageFormat.Jpeg);
                }

                rasterizer.Close();
            }
            return(outputFiles);
        }
Exemplo n.º 12
0
        public static List<string> PDFToImages(string file, string outputDirectory, int dpi, bool uniqueFileNames)
        {
            //string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            //path + @"\libs\gsdll32.dll"
            Ghostscript.NET.Rasterizer.GhostscriptRasterizer rasterizer = null;
            Ghostscript.NET.GhostscriptVersionInfo vesion = new Ghostscript.NET.GhostscriptVersionInfo(new Version(0, 0, 0), HostingEnvironment.MapPath("~/Libs/gsdll32.dll") , string.Empty, Ghostscript.NET.GhostscriptLicense.GPL);
            List<string> outputFiles = new List<string>();

            using (rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
            {
                rasterizer.Open(file, vesion, false);

                for (int i = 1; i <= rasterizer.PageCount; i++)
                {
                    string pageFilePath = Path.Combine(outputDirectory, (uniqueFileNames ? Path.GetRandomFileName() : "") + Path.GetFileNameWithoutExtension(file) + "-p" + i.ToString() + ".jpg");
                    outputFiles.Add(pageFilePath);
                    Image img = rasterizer.GetPage(dpi, dpi, i);
                    img.Save(pageFilePath, ImageFormat.Jpeg);
                }

                rasterizer.Close();
            }
            return outputFiles;
        }
        public void Generate(Indulgence indulgence, string fontsDirectory, string contentDirectory, string bkFilename,
            string pdfFilename, string imageThumbnailFileName_1, string imageThumbnailFileName_2,
            string imageThumbnailFileName_3, string imageThumbnailFileName_4)
        {
            string thumb1Filename = imageThumbnailFileName_1;
            string thumb2Filename = imageThumbnailFileName_2;
            string thumb3Filename = imageThumbnailFileName_3;
            string thumb4Filename = imageThumbnailFileName_4;

            Rectangle background = PageSize.LETTER.Rotate();
            background.BackgroundColor = new BaseColor(0, 0, 0, 0);
            Document doc = new Document(PageSize.LETTER.Rotate(), 20, 20, 0, 0); // 70, 70, 130, 70

            byte[] pdfData = null;
            using (var ms = new System.IO.MemoryStream())
            {
                var pdfWriter = PdfWriter.GetInstance(doc, ms);
                pdfWriter.PageEvent = new ParchmentPageEventHelper(_storage, contentDirectory, bkFilename);

                BaseFont uechiGothicBase = BaseFont.CreateFont(System.IO.Path.Combine(fontsDirectory, "UECHIGOT.ttf"),
                    BaseFont.CP1252, BaseFont.EMBEDDED);
                BaseFont trajanProBase =
                    BaseFont.CreateFont(System.IO.Path.Combine(fontsDirectory, "TrajanPro-Regular.otf"), BaseFont.CP1252,
                        BaseFont.EMBEDDED);
                Font uechiGothic = new Font(uechiGothicBase, 150, iTextSharp.text.Font.NORMAL, new BaseColor(139, 0, 0));

                Font trajanProConfession = new Font(trajanProBase, 45, iTextSharp.text.Font.BOLDITALIC,
                    new BaseColor(139, 0, 0));

                Font trajanProBoldSmall = new Font(trajanProBase, 24, Font.BOLD, new BaseColor(139, 54, 38));
                Font trajanProAttribution = new Font(trajanProBase, 24, iTextSharp.text.Font.NORMAL,
                    new BaseColor(139, 54, 38));

                doc.Open();

                var t = new PdfPTable(1);
                t.WidthPercentage = 100;
                var c = new PdfPCell();
                c.VerticalAlignment = Element.ALIGN_MIDDLE;
                c.MinimumHeight = doc.PageSize.Height - (doc.BottomMargin + doc.TopMargin);

                // confession
                Phrase firstLetterPhrase = new Phrase(indulgence.Confession.Substring(0, 1).ToUpper(), uechiGothic);
                Phrase confessionPhrase = new Phrase(indulgence.Confession.Substring(1), trajanProConfession);
                var confessionParagraph = new Paragraph(firstLetterPhrase);
                confessionParagraph.Add(confessionPhrase);
                confessionParagraph.Alignment = iTextSharp.text.Image.ALIGN_CENTER;
                confessionParagraph.Leading = 45;

                // attribution
                List<Phrase> phrases = new List<Phrase>();
                phrases.Add(new Phrase("On this ", trajanProAttribution));
                phrases.Add(new Phrase(TextUtils.DayOfMonth(indulgence.DateConfessed), trajanProBoldSmall));
                phrases.Add(new Phrase(" day of ", trajanProAttribution));
                phrases.Add(new Phrase(string.Format("{0:MMMM}", indulgence.DateConfessed), trajanProBoldSmall));
                phrases.Add(new Phrase(" in the year of our Lord ", trajanProAttribution));
                phrases.Add(new Phrase(indulgence.DateConfessed.Year.ToString(), trajanProBoldSmall));
                phrases.Add(new Phrase(", ", trajanProAttribution));
                var attributionName = indulgence.Name;
                if (string.IsNullOrWhiteSpace(attributionName))
                {
                    attributionName = "An Anonymous Believer";
                }
                phrases.Add(new Phrase(attributionName, trajanProBoldSmall));
                phrases.Add(new Phrase(" selflessly gave the sum of ", trajanProAttribution));
                phrases.Add(new Phrase(string.Format("{0:c}", indulgence.AmountDonated), trajanProBoldSmall));
                phrases.Add(new Phrase(" to the deserving organisation ", trajanProAttribution));
                phrases.Add(new Phrase(indulgence.CharityName, trajanProBoldSmall));
                phrases.Add(new Phrase(" and received this plenary indulgence", trajanProAttribution));

                var attribution = new Paragraph();
                confessionParagraph.Add(Environment.NewLine);
                foreach (var phrase in phrases)
                    confessionParagraph.Add(phrase);
                attribution.Leading = 24;
                /*attribution.Insert(0, attributionName);
            attribution.Add(attributionDonation);
            attribution.Add(attributionTo);
            attribution.Add(attributionCharity);*/
                attribution.SpacingBefore = 30;
                c.AddElement(confessionParagraph);
                t.AddCell(c);
                doc.Add(t);

                doc.Close();
                pdfData = ms.ToArray();
            }

            _storage.Store(pdfFilename, pdfData, true);

            System.Drawing.Image img = null;
            using (MemoryStream pdfStream = new MemoryStream(pdfData))
            using (MemoryStream pngStream = new MemoryStream())
            {
                GhostscriptVersionInfo gvi =
                    new GhostscriptVersionInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"gsdll32.dll"));
                using (var rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
                {
                    rasterizer.Open(pdfStream, gvi, true);
                    rasterizer.EPSClip = false;
                    img = rasterizer.GetPage(96, 96, 1);
                    img.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    img.Save(pngStream, ImageFormat.Png);
                    _storage.Store(thumb1Filename, pngStream.ToArray(), true);
                }
            }

            float ratio = (float)img.Height/(float)img.Width;
            SaveThumbnail(img, new SizeF(800, 800*ratio), thumb2Filename);
            SaveThumbnail(img, new SizeF(300, 300*ratio), thumb3Filename);
            SaveThumbnail(img, new SizeF(150, 150*ratio), thumb4Filename);

            // TODO: generate thumbnails as byte arrays and store to IFileStorage
        }
Exemplo n.º 14
0
        public void Generate(Indulgence indulgence, string fontsDirectory, string contentDirectory, string bkFilename,
                             string pdfFilename, string imageThumbnailFileName_1, string imageThumbnailFileName_2,
                             string imageThumbnailFileName_3, string imageThumbnailFileName_4)
        {
            string thumb1Filename = imageThumbnailFileName_1;
            string thumb2Filename = imageThumbnailFileName_2;
            string thumb3Filename = imageThumbnailFileName_3;
            string thumb4Filename = imageThumbnailFileName_4;

            Rectangle background = PageSize.LETTER.Rotate();

            background.BackgroundColor = new BaseColor(0, 0, 0, 0);
            Document doc = new Document(PageSize.LETTER.Rotate(), 20, 20, 0, 0); // 70, 70, 130, 70

            byte[] pdfData = null;
            using (var ms = new System.IO.MemoryStream())
            {
                var pdfWriter = PdfWriter.GetInstance(doc, ms);
                pdfWriter.PageEvent = new ParchmentPageEventHelper(_storage, contentDirectory, bkFilename);

                BaseFont uechiGothicBase = BaseFont.CreateFont(System.IO.Path.Combine(fontsDirectory, "UECHIGOT.ttf"),
                                                               BaseFont.CP1252, BaseFont.EMBEDDED);
                BaseFont trajanProBase =
                    BaseFont.CreateFont(System.IO.Path.Combine(fontsDirectory, "TrajanPro-Regular.otf"), BaseFont.CP1252,
                                        BaseFont.EMBEDDED);
                Font uechiGothic = new Font(uechiGothicBase, 150, iTextSharp.text.Font.NORMAL, new BaseColor(139, 0, 0));

                Font trajanProConfession = new Font(trajanProBase, 45, iTextSharp.text.Font.BOLDITALIC,
                                                    new BaseColor(139, 0, 0));

                Font trajanProBoldSmall   = new Font(trajanProBase, 24, Font.BOLD, new BaseColor(139, 54, 38));
                Font trajanProAttribution = new Font(trajanProBase, 24, iTextSharp.text.Font.NORMAL,
                                                     new BaseColor(139, 54, 38));

                doc.Open();

                var t = new PdfPTable(1);
                t.WidthPercentage = 100;
                var c = new PdfPCell();
                c.VerticalAlignment = Element.ALIGN_MIDDLE;
                c.MinimumHeight     = doc.PageSize.Height - (doc.BottomMargin + doc.TopMargin);


                // confession
                Phrase firstLetterPhrase   = new Phrase(indulgence.Confession.Substring(0, 1).ToUpper(), uechiGothic);
                Phrase confessionPhrase    = new Phrase(indulgence.Confession.Substring(1), trajanProConfession);
                var    confessionParagraph = new Paragraph(firstLetterPhrase);
                confessionParagraph.Add(confessionPhrase);
                confessionParagraph.Alignment = iTextSharp.text.Image.ALIGN_CENTER;
                confessionParagraph.Leading   = 45;


                // attribution
                List <Phrase> phrases = new List <Phrase>();
                phrases.Add(new Phrase("On this ", trajanProAttribution));
                phrases.Add(new Phrase(TextUtils.DayOfMonth(indulgence.DateConfessed), trajanProBoldSmall));
                phrases.Add(new Phrase(" day of ", trajanProAttribution));
                phrases.Add(new Phrase(string.Format("{0:MMMM}", indulgence.DateConfessed), trajanProBoldSmall));
                phrases.Add(new Phrase(" in the year of our Lord ", trajanProAttribution));
                phrases.Add(new Phrase(indulgence.DateConfessed.Year.ToString(), trajanProBoldSmall));
                phrases.Add(new Phrase(", ", trajanProAttribution));
                var attributionName = indulgence.Name;
                if (string.IsNullOrWhiteSpace(attributionName))
                {
                    attributionName = "An Anonymous Believer";
                }
                phrases.Add(new Phrase(attributionName, trajanProBoldSmall));
                phrases.Add(new Phrase(" selflessly gave the sum of ", trajanProAttribution));
                phrases.Add(new Phrase(string.Format("{0:c}", indulgence.AmountDonated), trajanProBoldSmall));
                phrases.Add(new Phrase(" to the deserving organisation ", trajanProAttribution));
                phrases.Add(new Phrase(indulgence.CharityName, trajanProBoldSmall));
                phrases.Add(new Phrase(" and received this plenary indulgence", trajanProAttribution));

                var attribution = new Paragraph();
                confessionParagraph.Add(Environment.NewLine);
                foreach (var phrase in phrases)
                {
                    confessionParagraph.Add(phrase);
                }
                attribution.Leading = 24;

                /*attribution.Insert(0, attributionName);
                 * attribution.Add(attributionDonation);
                 * attribution.Add(attributionTo);
                 * attribution.Add(attributionCharity);*/
                attribution.SpacingBefore = 30;
                c.AddElement(confessionParagraph);
                t.AddCell(c);
                doc.Add(t);

                doc.Close();
                pdfData = ms.ToArray();
            }

            _storage.Store(pdfFilename, pdfData, true);

            System.Drawing.Image img = null;
            using (MemoryStream pdfStream = new MemoryStream(pdfData))
                using (MemoryStream pngStream = new MemoryStream())
                {
                    GhostscriptVersionInfo gvi =
                        new GhostscriptVersionInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"gsdll32.dll"));
                    using (var rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
                    {
                        rasterizer.Open(pdfStream, gvi, true);
                        rasterizer.EPSClip = false;
                        img = rasterizer.GetPage(96, 96, 1);
                        img.RotateFlip(RotateFlipType.Rotate90FlipNone);
                        img.Save(pngStream, ImageFormat.Png);
                        _storage.Store(thumb1Filename, pngStream.ToArray(), true);
                    }
                }

            float ratio = (float)img.Height / (float)img.Width;

            SaveThumbnail(img, new SizeF(800, 800 * ratio), thumb2Filename);
            SaveThumbnail(img, new SizeF(300, 300 * ratio), thumb3Filename);
            SaveThumbnail(img, new SizeF(150, 150 * ratio), thumb4Filename);

            // TODO: generate thumbnails as byte arrays and store to IFileStorage
        }