EnlargeQRCode.cs
//
// This code is part of Document Solutions for Imaging demos.
// Copyright (c) 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
{
    // This sample shows the results of enlarging a small (57 by 57 pixels) image
    // of a QRCode using the 4 available interpolation modes.
    // While for most images (such as portraits or landscapes), Linear or Cubic
    // interpolation modes would normally yield better-looking results,
    // for images like QRCodes or barcodes using the NearestNeighbor or
    // Downscale modes is more appropriate.
    //
    // See EnlargeImage for an example where a small photo (portrait of a woman)
    // is enlarged using the same 4 interpolation modes.
    public class EnlargeQRCode
    {
        public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
        {
            // Create and clear the target bitmap:
            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", "times.ttf")),
                FontSize = fontSize,
            };

            // Small image of a QRCode:
            using var origBmp = new GcBitmap();
            using (var stm = File.OpenRead(Path.Combine("Resources", "ImagesBis", "QRCode-57x57.png")))
                origBmp.Load(stm);

            // Make sure opaqueness of the original bitmap matches the target:
            origBmp.Opaque = targetBmp.Opaque;

            var ip = new Point(xpad, ypad);

            // Draw the original with the original size:
            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;

            // We are going to enlarge the original small image by a factor of 6:
            var f = 6;
            int twidth = origBmp.PixelWidth * f;
            int theight = origBmp.PixelHeight * f;

            // Enlarge and draw 4 copies of the image using the 4 available interpolation modes:
            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;
        }
    }
}