EnlargeQRCode.cs
// 
// このコードは、DioDocs for Imaging のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
// 
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;

namespace DsImagingWeb.Demos
{
    // このサンプルは、小さな(57×57 ピクセル)QRCode の画像を、
    // 利用可能な 4 種類の補間モードを使用して拡大した結果を示します。
    // 一般的な画像(人物写真や風景など)の場合は、Linear や Cubic の
    // 補間モードの方が、通常は見た目の良い結果が得られますが、
    // QRCode やバーコードのような画像では、NearestNeighbor や
    // Downscale モードを使用する方が適切です。
    //
    // 同じ 4 種類の補間モードを使用して小さな写真(女性のポートレート)を
    // 拡大する例については、EnlargeImage を参照してください。
    public class EnlargeQRCode
    {
        public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
        {
            // ターゲットビットマップを作成してクリアします。
            var targetBmp = new GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi);
            targetBmp.Clear(Color.Transparent);

            const int fontSize = 16;
            var xpad = (int)(dpi * .5f);
            var ypad = (int)(dpi * .7f);
            TextFormat tf = new TextFormat
            {
                Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSerif.ttf")),
                FontSize = fontSize,
            };

            // QRコードの小さな画像です。
            using var origBmp = new GcBitmap();
            using (var stm = File.OpenRead(Path.Combine("Resources", "ImagesBis", "QRCode-57x57.png")))
                origBmp.Load(stm);

            // 元のビットマップの不透明度がターゲットと一致することを確認します。
            origBmp.Opaque = targetBmp.Opaque;

            var ip = new Point(xpad, ypad);

            // 元の画像を元のサイズで描画します。
            targetBmp.BitBlt(origBmp, ip.X, ip.Y);
            using (var g = targetBmp.CreateGraphics(null))
                g.DrawString($"⟵ Original image ({origBmp.PixelWidth} by {origBmp.PixelHeight} pixels)", tf, new PointF(xpad * 2 + origBmp.Width, ip.Y));
            ip.Y += origBmp.PixelHeight + ypad;

            // 元の小さな画像を6倍に拡大します。
            var f = 6;
            int twidth = origBmp.PixelWidth * f;
            int theight = origBmp.PixelHeight * f;

            // 利用可能な4つの補間モードを使用して、画像を6倍に拡大して描画します。
            using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.NearestNeighbor))
                targetBmp.BitBlt(bmp, ip.X, ip.Y);
            drawCaption("InterpolationMode.NearestNeighbor", ip.X, ip.Y + theight);

            using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.Cubic))
                targetBmp.BitBlt(bmp, ip.X + twidth + xpad, ip.Y);
            drawCaption("InterpolationMode.Cubic", ip.X + twidth + xpad, ip.Y + theight);

            ip.Y += theight + ypad;

            using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.Linear))
                targetBmp.BitBlt(bmp, ip.X, ip.Y);
            drawCaption("InterpolationMode.Linear", ip.X, ip.Y + theight);

            using (var bmp = origBmp.Resize(twidth, theight, InterpolationMode.Downscale))
                targetBmp.BitBlt(bmp, ip.X + twidth + xpad, ip.Y);
            drawCaption("InterpolationMode.Downscale", ip.X + twidth + xpad, ip.Y + theight);

            // キャプションを描画するためのローカルヘルパー
            void drawCaption(string caption, float x, float y)
            {
                using var g = targetBmp.CreateGraphics(null);
                g.DrawString(caption, tf, new PointF(x, y));
            }
            return targetBmp;
        }
    }
}