InterpolationModes.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © 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
{
    // このサンプルでは、SaveAsJpeg や他の SaveAsXXX メソッドを使用して PDF をラスター画像に保存する際に、
    // SaveAsImageOptions.InterpolationMode を指定することで、出力結果にどのような影響を与えるかを紹介しています。
    public class InterpolationModes
    {
        public int CreatePDF(Stream stream)
        {
            // PDF に拡大して追加する小さい QRCode の画像です。
            using var image = GCDRAW.Image.FromFile(Path.Combine("Resources", "ImagesBis", "QRCode-57x57.png"));

            // 小さい QRCode の画像を拡大して追加した1ページ分の PDF を4つ作成し、
            // 各 PDF を SaveAsImageOptions で指定した異なる補間モードで JPEG として保存します。
            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);

            // 各 JPEG をそのままの大きさで、結果として出力する PDF に1ページずつ描画します。
            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);
            // 結果の PDF を保存します。
            doc.Save(stream);

            // クリーンアップします。
            File.Delete(tmpNearestNeighbor);
            File.Delete(tmpLinear);
            File.Delete(tmpCubic);
            File.Delete(tmpDownscale);

            // PDF ドキュメントを保存します。
            return doc.Pages.Count;
        }

        // ここでの InterpolationMode パラメータは、最終的に出力する PDF に情報を描画するためだけのものです。
        // PDF の描画に使用する GcPdfGraphics は、InterpolationMode.NearestNeighbor のみをサポートしています。
        public GcPdfDocument MakePDF(GCDRAW.Image image, InterpolationMode imode)
        {
            var tfCaption = new TextFormat
            {
                Font = Common.Util.getFont(),
                FontSize = 20,
            };
            var tf = new TextFormat
            {
                Font = Common.Util.getFont(),
                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 は {imode}", tfCaption, ip);
            ip.Y *= 2.5f;

            // QRCode の画像をそのままのサイズで描画します。
            g.DrawImage(image, new RectangleF(ip.X, ip.Y, image.Width, image.Height), null, ImageAlign.Default);
            g.DrawString($"← 元の画像({image.Width} × {image.Height} ピクセル)", tf, new PointF(ip.X * 2 + image.Width, ip.Y));
            ip.Y += image.Height + ypad;

            // 元の小さな画像を8倍に拡大します。
            var f = 8;
            int twidth = image.Width * f;
            int theight = image.Height * f;

            // 拡大した画像を描画します。
            g.DrawImage(image, new RectangleF(ip.X, ip.Y, twidth, theight), null, ImageAlign.StretchImage);
            g.DrawString($"{twidth} × {theight} ピクセルに拡大した画像:", tf, new PointF(ip.X, ip.Y - ypad));

            return doc;
        }
    }
}