PdfToGrayscaleTiff.cs
//
// This code is part of Document Solutions for PDF demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Annotations;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GrapeCity.Documents.Drawing;

namespace DsPdfWeb.Demos
{
    // This example shows how to convert an arbitrary PDF to a multi-frame TIFF
    // in which each frame corresponds to a single PDF page, converting full color
    // original pages to grayscale images with an arbitrary target resolution
    // (in the sample code the resolution is set to 200 dpi).
    //
    // Note that while the code in this example uses some DsImaging features,
    // it does not need a DsImaging license to work without issues.
    // See PdfToTiffDsImaging for an example that does the same conversion faster,
    // but does require a valid DsImaging license.
    //
    // In order to seamlessly build this sample into the demo site framework,
    // the generated TIFF is then converted back into a PDF. In a real life scenario
    // you can just use the code that generates the TIFF directly.
    public class PdfToGrayscaleTiff
    {
        public int CreatePDF(Stream stream)
        {
            // Arbitrary target DPI for the generated TIFF, adjust as needed:
            const int targetDPI = 200;

            var inputDoc = new GcPdfDocument();
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "SlidePages.pdf"));
            inputDoc.Load(fs);

            using var ms = new MemoryStream();
            using var bmp = new GcBitmap();
            // NOTE: to produce a TIFF disk file, you would create a GcTiffWriter
            // with the file path as the parameter. But due to the demo browser requirements,
            // we create a GcTiffWriter on a memory stream instead:
            // using var tiffWriter = new GcTiffWriter("result.tiff");
            using var msTiff = new MemoryStream();
            using (var tiffWriter = new GcTiffWriter(msTiff))
            {
                foreach (var p in inputDoc.Pages)
                {
                    // Save each PDF page as PNG with target resolution:
                    ms.Position = 0;
                    p.SaveAsPng(ms, new SaveAsImageOptions { Resolution = targetDPI });
                    ms.Position = 0;
                    bmp.Load(ms);
                    // Load the PNG into GcBitmap, apply in-place grayscale effect,
                    // convert to grayscale bitmap and append it to the TIFF:
                    bmp.ApplyEffect(GrayscaleEffect.Get());
                    using var gbmp = bmp.ToGrayscaleBitmap();
                    tiffWriter.AppendFrame(gbmp);
                }
            }
            // At this point tiffWriter has the newly created TIFF. If it was created on
            // a disk file, that file would contain the TIFF when tiffWriter is disposed.
            //
            // To use this sample in the demo browser, we have to convert the TIFF
            // back to a PDF that is returned to the controller.
            msTiff.Position = 0;
            var doc = new GcPdfDocument();
            using var tiffReader = new GcTiffReader(msTiff);
            List<IDisposable> disposables = new List<IDisposable>();
            foreach (var tp in tiffReader.Frames)
            {
                var img = tp.ToImage(ImageBinding.InMemoryData);
                var p = doc.Pages.Add(new SizeF(img.Width / img.HorizontalResolution * 72, img.Height / img.VerticalResolution * 72));
                p.Graphics.DrawImage(img, p.Bounds, null, ImageAlign.Default);
                disposables.Add(img);
            }
            // Save the PDF:
            doc.Save(stream);
            // We can only dispose images after saving the PDF:
            disposables.ForEach(d_ => d_.Dispose());
            return doc.Pages.Count;
        }
    }
}