ExtractFrames.cs
//
// This code is part of GrapeCity Documents for Imaging samples.
// Copyright (c) GrapeCity, Inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;

namespace GcImagingWeb.Samples
{
    // This sample shows how to extract frames from a TIFF image,
    // and how to read them as GcBitmap instances.
    public class ExtractFrames
    {
        public GcBitmap GenerateImage(int pixelWidth = 1024, int pixelHeight = 1024, bool opaque = true, float dpiX = 96, float dpiY = 96)
        {
            // Create the resulting image:
            var bmp = new GcBitmap(pixelWidth, pixelHeight, opaque, dpiX, dpiY);

            // If there is a possibility that we will not fill some areas of the target bitmap
            // (as in this case where the number of frames in the TIFF may be less than 4),
            // we MUST clear the resulting bitmap as GcBitmap ctor does NOT clear the memory
            // allocated for the pixels (to save time, as initializing large bitmaps may be
            // very slow):
            bmp.Clear();

            // Sample TIFF image path:
            var imagePath = Path.Combine("Resources", "ImagesBis", "BmpWriteTiff3.tiff");

            // List to hold bitmaps for the TIFF frames:
            GcBitmap[] frameBmps;

            // Read all frames from the TIFF file:
            using (var stm = new FileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.RandomAccess))
            using (var tr = new GcTiffReader(stm))
            {
                frameBmps = new GcBitmap[tr.Frames.Count];
                for (int i = 0; i < tr.Frames.Count; ++i)
                {
                    frameBmps[i] = tr.Frames[i].ToGcBitmap();
                    frameBmps[i].Opaque = opaque;
                }
            }

            // Resize and render the frames' bitmaps into the resulting image:
            int w = pixelWidth / 2;
            int h = pixelHeight / 2;
            if (frameBmps.Length > 0)
                using (var tbmp = frameBmps[0].Resize(w, h))
                    bmp.BitBlt(tbmp, 0, 0);
            if (frameBmps.Length > 1)
                using (var tbmp = frameBmps[1].Resize(w, h))
                    bmp.BitBlt(tbmp, w, 0);
            if (frameBmps.Length > 2)
                using (var tbmp = frameBmps[2].Resize(w, h))
                    bmp.BitBlt(tbmp, 0, h);
            if (frameBmps.Length > 3)
                using (var tbmp = frameBmps[3].Resize(w, h))
                    bmp.BitBlt(tbmp, w, h);

            // Dispose the frame bitmaps:
            foreach (var tbmp in frameBmps)
                tbmp.Dispose();

            // Add borders between the quadrants, and captions for each:
            using (var g = bmp.CreateGraphics())
            {
                var foreColor = Color.Yellow;
                var backColor = Color.Blue;
                var font = Font.FromFile(Path.Combine("Resources", "Fonts", "cour.ttf"));
                var lineh = 2;
                g.DrawLine(w, 0, w, h * 2, new Pen(Color.Gray, lineh * 2));
                g.DrawLine(0, h, w * 2, h, new Pen(Color.Gray, lineh * 2));
                var tf = new TextFormat() { Font = font, FontSize = 18, ForeColor = foreColor, BackColor = backColor, FontBold = true };
                var th = g.MeasureString("QWERTY", tf).Height;
                if (frameBmps.Length > 0)
                    g.DrawString(" Frame 0 ", tf, new PointF(0, h - th + lineh));
                if (frameBmps.Length > 1)
                    g.DrawString(" Frame 1 ", tf, new PointF(w + lineh, h - th + lineh));
                if (frameBmps.Length > 2)
                    g.DrawString(" Frame 2 ", tf, new PointF(0, h * 2 + lineh - th + lineh));
                if (frameBmps.Length > 3)
                    g.DrawString(" Frame 3 ", tf, new PointF(w + lineh, h * 2 + lineh - th + lineh));
            }

            return bmp;
        }
    }
}