InterpolationModes.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 GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Drawing;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;

namespace DsPdfWeb.Demos
{
    // This example shows how SaveAsImageOptions.InterpolationMode affects the result
    // when a PDF is saved to raster images using SaveAsJpeg or other SaveAsXXX methods.
    public class InterpolationModes
    {
        public int CreatePDF(Stream stream)
        {
            // Small image of a QRCode that will be enlarged in PDFs that are then saved as JPEGs:
            using var image = GCDRAW.Image.FromFile(Path.Combine("Resources", "ImagesBis", "QRCode-57x57.png"));

            // Create 4 PDFs, each is one page on which the small image is enlarged,
            // save each PDF as JPEG with different interpolation modes specified in SaveAsImageOptions:
            var tmpNearestNeighbor = Path.GetTempFileName();
            MakePDF(image, InterpolationMode.NearestNeighbor).SaveAsJpeg(tmpNearestNeighbor, null, 
                new SaveAsImageOptions() { InterpolationMode = InterpolationMode.NearestNeighbor });
            using var imgNearestNeighbor = GCDRAW.Image.FromFile(tmpNearestNeighbor);
            var tmpLinear = Path.GetTempFileName();
            MakePDF(image, InterpolationMode.Linear).SaveAsJpeg(tmpLinear, null,
                new SaveAsImageOptions() { InterpolationMode = InterpolationMode.Linear });
            using var imgLinear = GCDRAW.Image.FromFile(tmpLinear);
            var tmpCubic = Path.GetTempFileName();
            MakePDF(image, InterpolationMode.Cubic).SaveAsJpeg(tmpCubic, null,
                new SaveAsImageOptions() { InterpolationMode = InterpolationMode.Cubic });
            using var imgCubic = GCDRAW.Image.FromFile(tmpCubic);
            var tmpDownscale = Path.GetTempFileName();
            MakePDF(image, InterpolationMode.Downscale).SaveAsJpeg(tmpDownscale, null,
                new SaveAsImageOptions() { InterpolationMode = InterpolationMode.Downscale });
            using var imgDownscale = GCDRAW.Image.FromFile(tmpDownscale);

            // Draw each JPEG at its natural size onto a page of the resulting PDF:
            var doc = new GcPdfDocument();
            var page = doc.NewPage();
            page.Graphics.DrawImage(imgNearestNeighbor, page.Bounds, null, ImageAlign.Default);
            page = doc.NewPage();
            page.Graphics.DrawImage(imgLinear, page.Bounds, null, ImageAlign.Default);
            page = doc.NewPage();
            page.Graphics.DrawImage(imgCubic, page.Bounds, null, ImageAlign.Default);
            page = doc.NewPage();
            page.Graphics.DrawImage(imgDownscale, page.Bounds, null, ImageAlign.Default);
            // Save the resulting PDF:
            doc.Save(stream);
            // CLeanup:
            File.Delete(tmpNearestNeighbor);
            File.Delete(tmpLinear);
            File.Delete(tmpCubic);
            File.Delete(tmpDownscale);

            // Done:
            return doc.Pages.Count;
        }

        // InterpolationMode parameter here is only to show in the resulting PDF,
        // GcPdfGraphics only supports InterpolationMode.NearestNeighbor:
        public GcPdfDocument MakePDF(GCDRAW.Image image, InterpolationMode imode)
        {
            var tfCaption = new TextFormat
            {
                Font = StandardFonts.Times,
                FontSize = 20,
            };
            var tf = new TextFormat
            {
                Font = StandardFonts.Times,
                FontSize = 18,
            };

            var doc = new GcPdfDocument();
            var page = doc.NewPage();
            var g = page.Graphics;

            var xpad = 36;
            var ypad = 36;
            var ip = new PointF(xpad, ypad);
            g.DrawString($"SaveAsImageOptions.InterpolationMode is {imode}", tfCaption, ip);
            ip.Y *= 2.5f;

            // Draw the original with the original size:
            g.DrawImage(image, new RectangleF(ip.X, ip.Y, image.Width, image.Height), null, ImageAlign.Default);
            g.DrawString($"⟵ Original image ({image.Width} by {image.Height} pixels)", tf, new PointF(ip.X * 2 + image.Width, ip.Y));
            ip.Y += image.Height + ypad;

            // Enlarge the original small image by a factor of 8:
            var f = 8;
            int twidth = image.Width * f;
            int theight = image.Height * f;

            // Draw the enlarged image:
            g.DrawImage(image, new RectangleF(ip.X, ip.Y, twidth, theight), null, ImageAlign.StretchImage);
            g.DrawString($"Image enlarged to {twidth} by {theight} pixels:", tf, new PointF(ip.X, ip.Y - ypad));

            return doc;
        }
    }
}