GetImageProperties.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.Graphics.Images;
using GrapeCity.Documents.Pdf.Spec;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Drawing;

namespace DsPdfWeb.Demos
{
    // This example shows how to fetch low level information about images living in a PDF file,
    // such as the ID of the image object in the PDF, the filter used to store the image,
    // the decoder parameters, the content of the PdfImage dictionary, etc.
    // The original PDF is appended to the result for reference.
    public class GetImageProperties
    {
        public int CreatePDF(Stream stream)
        {
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "Wetlands.pdf"));
            var docSrc = new GcPdfDocument();
            docSrc.Load(fs);

            // Get the images in the loaded PDF and print their info into the resulting PDF:
            var imageInfos = docSrc.GetImages();

            // The PDF to hold the results:
            var doc = new GcPdfDocument();
            var page = doc.NewPage();
            // Set up a TextLayout to format the results:
            var tl = page.Graphics.CreateTextLayout();
            tl.DefaultFormat.Font = StandardFonts.Courier;
            tl.DefaultFormat.FontSize = 14;
            tl.MaxWidth = doc.PageSize.Width;
            tl.MaxHeight = doc.PageSize.Height;
            tl.MarginAll = tl.Resolution;
            var captionFmt = new TextFormat(tl.DefaultFormat) { Font = StandardFonts.CourierBold, FontSize = tl.DefaultFormat.FontSize + 2 };

            int i = 0;
            foreach (var imageInfo in imageInfos)
            {
                tl.AppendLine($"Image {++i}", captionFmt);

                // PdfImageBase class represents an image in the loaded PDF file:
                PdfImageBase img = imageInfo.Image;

                tl.AppendLine($"PdfImage object ID: {img.ObjID}");
                // PdfImageBase is derived from PdfDictWrapper type, it has methods
                // that allow you to access properties/data of the underlying PDF stream object:
                using (PdfStreamInfo psi = img.GetPdfStreamInfo())
                {
                    tl.AppendLine($"    Image stream length: {psi.Stream.Length}");
                    tl.AppendLine($"        ImageFilterName: {psi.ImageFilterName}");
                    tl.AppendLine($"ImageFilterDecodeParams: {psi.ImageFilterDecodeParams}");
                    // Dump the content of the ImageFilterDecodeParams if it exists:
                    if (psi.ImageFilterDecodeParams != null)
                    {
                        foreach (var kvp in psi.ImageFilterDecodeParams.Dict)
                        {
                            tl.AppendLine($"{kvp.Key}: {kvp.Value}");
                        }
                        // An example of how to get the value of BlackIs1:
                        var blackIs1 = psi.ImageFilterDecodeParams.GetBool(PdfName.Std.BlackIs1, null);
                        tl.AppendLine($"BlackIs1: {blackIs1}");
                    }
                }
                // Dump the properties of PdfImage dictionary:
                tl.AppendLine();
                tl.AppendLine("Properties of PdfImage dictionary:");
                foreach (KeyValuePair<PdfName, IPdfObject> kvp in img.PdfDict.Dict)
                {
                    tl.AppendLine($"{kvp.Key}: {kvp.Value}");
                }
                // 
                var cs = img.Get<IPdfObject>(PdfName.Std.ColorSpace);
                tl.AppendLine($"ColorSpace: {cs.GetType().Name} {cs}");
                var bpc = img.Get<IPdfObject>(PdfName.Std.BitsPerComponent);
                tl.AppendLine($"BitsPerComponent: {bpc?.GetType().Name} {bpc}");
                tl.AppendLine();
            }

            // Render the results:
            tl.PerformLayout(true);
            while (true)
            {
                var splitResult = tl.Split(null, out TextLayout rest);
                page.Graphics.DrawTextLayout(tl, PointF.Empty);
                if (splitResult != SplitResult.Split)
                    break;
                tl = rest;
                tl.MarginTop = tl.Resolution;
                page = doc.Pages.Add();
            }

            // Append the source PDF to the result for reference:
            doc.MergeWithDocument(docSrc);

            // Done:
            doc.Save(stream);
            return doc.Pages.Count;
        }
    }
}