ImageArticles.cs
// 完毕:
using System;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Articles;
using GrapeCity.Documents.Imaging;
using GrapeCity.Documents.Drawing;
using DsPdfWeb.Demos.Common;
namespace DsPdfWeb.Demos
{
// 此示例演示如何在 PDF 文档中创建文章线索。
// 文章线索是一系列相关页面或页面区域,可以
// 在支持的 PDF 查看器中按顺序导航(向前或向后)。
// 在此示例中,我们从文件夹加载许多照片并渲染它们
// 每页一个,顺序随机。
// 有些照片(通过已知的文件名)与特定主题相关联
// (建筑物、艺术等),我们将所有与相关的图像
// 每个主题进入特定主题的文章线程(不是图像
// 与任何已知主题相关的内容都放在“杂项”线程中)。
// 此外,我们还为不同的纵横比创建了 3 个线程(水平、
// 垂直和方形),并将每个图像添加到相应的方面文章中。
// 请参阅 导览 PDF 页面
// 有关如何在 Acrobat 中导航文章线索的详细信息
// (我们的 JavaScript PDF 查看器为此提供了类似的 UI)。
public class ImageArticles
{
// 文章名称:
static class ArticleNames
{
public static string Landscape => "Subject: landscape";
public static string Art => "Subject: art";
public static string Flora => "Subject: flora";
public static string Buildings => "Subject: buildings";
public static string Misc => "Subject: Miscellaneous";
public static string AspectHorz => "Aspect: horizontal";
public static string AspectVert => "Aspect: vertical";
public static string AspectSquare => "Aspect: square";
}
// 将已知图像文件名与适当的主题相关联:
static readonly Dictionary<string, string> _subjects = new Dictionary<string, string>()
{
{"aurora.jpg", ArticleNames.Landscape },
{"chairs.jpg", ArticleNames.Buildings },
{"clouds.jpg", ArticleNames.Landscape },
{"colosseum.jpg", ArticleNames.Art },
{"deadwood.jpg", ArticleNames.Flora },
{"door.jpg", ArticleNames.Buildings },
{"ferns.jpg", ArticleNames.Flora },
{"fiord.jpg", ArticleNames.Landscape },
{"firth.jpg", ArticleNames.Landscape },
{"lady.jpg", ArticleNames.Art },
{"lavender.jpg", ArticleNames.Flora },
{"maple.jpg", ArticleNames.Buildings },
{"minerva.jpg", ArticleNames.Art },
{"newfoundland.jpg", ArticleNames.Landscape },
{"pines.jpg", ArticleNames.Flora },
{"purples.jpg", ArticleNames.Flora },
{"reds.jpg", ArticleNames.Flora },
{"road.jpg", ArticleNames.Landscape },
{"rome.jpg", ArticleNames.Art },
{"roofs.jpg", ArticleNames.Buildings },
{"sea.jpg", ArticleNames.Landscape },
{"skye.jpg", ArticleNames.Landscape },
{"tudor.jpg", ArticleNames.Buildings },
{"windswept.jpg", ArticleNames.Flora },
// 不在此列表中的图像为“杂项”。
};
// 保存图像信息的类:
private class ImageInfo
{
public string Name;
public IImage Image;
public string Subject;
public string Aspect;
}
public int CreatePDF(Stream stream)
{
// 加载图像及其相关信息:
var imageInfos = new List<ImageInfo>();
foreach (var fname in Directory.GetFiles(Path.Combine("Resources", "Images"), "*", SearchOption.AllDirectories))
{
var image = Util.ImageFromFile(fname);
var aspect = image.Width > image.Height ? ArticleNames.AspectHorz :
(image.Width < image.Height ? ArticleNames.AspectVert : ArticleNames.AspectSquare);
var name = Path.GetFileName(fname);
_subjects.TryGetValue(name, out string subject);
if (string.IsNullOrEmpty(subject))
subject = ArticleNames.Misc;
imageInfos.Add(new ImageInfo()
{
Name = name,
Image = image,
Subject = subject,
Aspect = aspect
});
}
// 随机化 PDF 中图像的顺序:
imageInfos.Shuffle();
// 键是文章主题名称(来自 ArticleNames),
// 值是要添加到 PDF 的 ArticleThread 对象:
var articles = new Dictionary<string, ArticleThread>();
foreach (var subject in _subjects.Values.Distinct())
articles.Add(subject,
new ArticleThread()
{
Info = new DocumentInfo() { Title = subject }
});
articles.Add(ArticleNames.Misc,
new ArticleThread()
{
Info = new DocumentInfo() { Title = ArticleNames.Misc }
});
var horizontals = new ArticleThread()
{
Info = new DocumentInfo() { Title = ArticleNames.AspectHorz }
};
var verticals = new ArticleThread()
{
Info = new DocumentInfo() { Title = ArticleNames.AspectVert }
};
var squares = new ArticleThread()
{
Info = new DocumentInfo() { Title = ArticleNames.AspectSquare }
};
// 创建文档:
var doc = new GcPdfDocument();
// 将图像(每页一张)添加到 PDF 和文章线程:
var ia = new ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Top, true, true, true, false, false);
for (int i = 0; i < imageInfos.Count; ++i)
{
var page = doc.NewPage();
var ii = imageInfos[i];
var rc = new RectangleF(72, 72, doc.PageSize.Width - 144, doc.PageSize.Height - 144);
// 请注意,我们获取实际图像边界以精确指定线程中的页面区域:
page.Graphics.DrawImage(ii.Image, rc, null, ia, out RectangleF[] imageBounds);
var bounds = imageBounds[0];
// 将图像添加到适当的主题和方面线程:
articles[ii.Subject].Beads.Add(new ArticleBead() { Page = page, Bounds = bounds });
if (ii.Aspect == ArticleNames.AspectHorz)
horizontals.Beads.Add(new ArticleBead() { Page = page, Bounds = bounds });
else if (ii.Aspect == ArticleNames.AspectVert)
verticals.Beads.Add(new ArticleBead() { Page = page, Bounds = bounds });
else
squares.Beads.Add(new ArticleBead() { Page = page, Bounds = bounds });
}
// 将主题和方面文章线程添加到 PDF:
foreach (var article in articles.Select(a_ => a_.Value))
doc.ArticleThreads.Add(article);
doc.ArticleThreads.Add(horizontals);
doc.ArticleThreads.Add(verticals);
doc.ArticleThreads.Add(squares);
// 完毕:
doc.Save(stream);
return doc.Pages.Count;
}
}
}