ShowExif.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 GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GrapeCity.Documents.Imaging.Exif;

namespace GcImagingWeb.Samples
{
    // Print the Exif tags found in an image.
    // See also ClearExif which uses the same code but removes the EXIF tags first.
    public class ShowExif
    {
        public GcBitmap GenerateImage (int pixelWidth = 1024, int pixelHeight = 1024, bool opaque = true, float dpiX = 96, float dpiY = 96)
        {
            var pad = 20;
            var side = pixelWidth / 3;
            var bmp = new GcBitmap(pixelWidth, pixelHeight, true, dpiX, dpiY);
            using (var g = bmp.CreateGraphics(Color.White))
            using (var testImage = new GcBitmap(Path.Combine("Resources", "ImagesBis", "fire.jpg")))
            {
                var tl = g.CreateTextLayout();
                tl.DefaultFormat.Font = Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf"));
                tl.DefaultFormat.FontSize = 11;
                tl.DefaultTabStops = 160;
                tl.MarginTop = pad;
                tl.MarginBottom = pad;
                tl.MarginLeft = pad * 2 + side;
                tl.MarginRight = pad;
                tl.MaxWidth = pixelWidth;
                AppendExifData(tl, testImage.ExifProfile);
                g.DrawImage(testImage, new RectangleF(pad, pad, side, side), null, ImageAlign.ScaleImage);
                if (tl.Lines.Count == 0)
                    tl.AppendLine("No EXIF tags found.");
                g.DrawTextLayout(tl, PointF.Empty);
            }
            return bmp;
        }

        void AppendExifData(TextLayout tl, ExifProfile ep)
        {
            Append(tl, ep, ExifTag.Make, ep.Make);
            Append(tl, ep, ExifTag.Model, ep.Model);
            Append(tl, ep, ExifTag.XResolution, ep.XResolution?.ToString());
            Append(tl, ep, ExifTag.YResolution, ep.YResolution?.ToString());
            Append(tl, ep, ExifTag.ResolutionUnit, ep.ResolutionUnit.ToString());
            Append(tl, ep, ExifTag.Software, ep.Software);
            Append(tl, ep, ExifTag.DateTime, ep.DateTimeRaw);
            Append(tl, ep, ExifTag.Artist, ep.Artist);
            Append(tl, ep, ExifTag.Copyright, ep.Copyright);
            Append(tl, ep, ExifTag.ExposureTime, ep.ExposureTime?.ToString());
            Append(tl, ep, ExifTag.FNumber, ep.FNumber?.ToString());
            Append(tl, ep, ExifTag.ExposureProgram, ep.ExposureProgram.ToString());
            Append(tl, ep, ExifTag.PhotographicSensitivity, ep.PhotographicSensitivity?.ToString());
            Append(tl, ep, ExifTag.ExifVersion, ep.ExifVersion);
            Append(tl, ep, ExifTag.DateTimeOriginal, ep.DateTimeOriginalRaw);
            Append(tl, ep, ExifTag.DateTimeDigitized, ep.DateTimeDigitizedRaw);
            Append(tl, ep, ExifTag.ShutterSpeedValue, ep.ShutterSpeedValue?.ToString());
            Append(tl, ep, ExifTag.ApertureValue, ep.ApertureValue?.ToString());
            Append(tl, ep, ExifTag.ExposureBiasValue, ep.ExposureBiasValue?.ToString());
            Append(tl, ep, ExifTag.MaxApertureValue, ep.MaxApertureValue?.ToString());
            Append(tl, ep, ExifTag.MeteringMode, ep.MeteringMode.ToString());
            Append(tl, ep, ExifTag.LightSource, ep.LightSource.ToString());
            Append(tl, ep, ExifTag.Flash, ep.Flash.ToString());
            Append(tl, ep, ExifTag.FocalLength, ep.FocalLength?.ToString());
            // First 8 symbols in UserComment specify encoding:
            Append(tl, ep, ExifTag.UserComment, ep.UserComment?.Substring(8));
            Append(tl, ep, ExifTag.SubsecTimeOriginal, ep.SubsecTimeOriginal?.ToString());
            Append(tl, ep, ExifTag.SubsecTimeDigitized, ep.SubsecTimeDigitized?.ToString());
            Append(tl, ep, ExifTag.ColorSpace, ep.ColorSpace.ToString());
            Append(tl, ep, ExifTag.SensingMethod, ep.SensingMethod.ToString());
            Append(tl, ep, ExifTag.FileSource, ep.FileSource.ToString());
            Append(tl, ep, ExifTag.SceneType, ep.SceneType?.ToString());
            Append(tl, ep, ExifTag.CFAPattern, ep[ExifTag.CFAPattern]?.ToString());
            Append(tl, ep, ExifTag.CustomRendered, ep.CustomRendered.ToString());
            Append(tl, ep, ExifTag.ExposureMode, ep.ExposureMode.ToString());
            Append(tl, ep, ExifTag.WhiteBalance, ep.WhiteBalance.ToString());
            Append(tl, ep, ExifTag.DigitalZoomRatio, ep.DigitalZoomRatio?.ToString());
            Append(tl, ep, ExifTag.FocalLengthIn35mmFilm, ep.FocalLengthIn35mmFilm?.ToString());
            Append(tl, ep, ExifTag.SceneCaptureType, ep.SceneCaptureType.ToString());
            Append(tl, ep, ExifTag.Contrast, ep.Contrast.ToString());
            Append(tl, ep, ExifTag.Saturation, ep.Saturation.ToString());
            Append(tl, ep, ExifTag.Sharpness, ep.Sharpness.ToString());
            Append(tl, ep, ExifTag.SubjectDistanceRange, ep.SubjectDistanceRange.ToString());
            Append(tl, ep, ExifTag.BodySerialNumber, ep.BodySerialNumber);
            Append(tl, ep, ExifTag.LensSpecification, ep[ExifTag.LensSpecification]?.ToString());
            Append(tl, ep, ExifTag.LensModel, ep.LensModel);
        }

        void Append(TextLayout tl, ExifProfile ep, ExifTag tag, string text)
        {
            if (ep.HasValue(tag))
            {
                tl.AppendLine(tag.ToString() + '\t' + text);
            }
        }
    }
}