内容目录
源文件是 PDF 全元素,也就是各种点线、文字、表格组成,需要将内容全部转成图片形式存储到 pdf 中。
引入:
<ItemGroup>
<PackageReference Include="FreeSpire.PDF" Version="8.6.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
</ItemGroup>
internal class Program
{
private static readonly RecyclableMemoryStreamManager StreamManager = new();
[SupportedOSPlatform("windows")]
static async Task Main()
{
using PdfDocument oldPdf = new PdfDocument();
using PdfDocument newPdf = new PdfDocument();
oldPdf.LoadFromFile("old.pdf");
for (int i = 0; i < oldPdf.Pages.Count; i++)
{
PdfPageBase oldPage = oldPdf.Pages[i];
var newPage = newPdf.AppendPage();
// 将页面转为图片
Image image = oldPdf.SaveAsImage(i, PdfImageType.Bitmap);
using var stream = StreamManager.GetStream();
image.Save(stream, ImageFormat.Png);
// 新的 pdf 插入图片到页面
var pdfImage = PdfImage.FromStream(stream);
var size = GetSize(newPage, image);
// 插入图片并设置坐标轴
newPage.Canvas.DrawImage(pdfImage, new PointF(0, 0), size);
}
newPdf.SaveToFile("new.pdf");
}
/// <summary>
/// 图片放大缩小<br />
/// 如果过长图片过大,则自动缩小。<br />
/// 如果图片小,则自动水平居中。
/// </summary>
/// <param name="page"></param>
/// <param name="image"></param>
/// <returns></returns>
[SupportedOSPlatform("windows")]
static SizeF GetSize(PdfPageBase page, Image image)
{
float x = 0; // 图片在页面上的横坐标
//float y = 0; // 图片在页面上的纵坐标
float imageWidth = image.Width;
float imageHeight = image.Height;
// ClientSize 获取到的才是真正可以显示的区域,去掉了边框,Size 是纸张全部区域
var clientSize = page.GetClientSize();
float pageWidth = clientSize.Width;
float pageHeight = clientSize.Height;
// 最终计算结果
float width = image.Width;
float height = image.Height;
// 图片过长时
if (imageWidth >= pageWidth)
{
float ratio = imageWidth / pageWidth;
width = pageWidth;
height = imageHeight / ratio;
}
// 图片小于页面,则居中
else if (imageHeight < pageWidth)
{
x = (pageWidth - imageWidth) / 2;
}
return new SizeF(width: width, height: height);
}
}
文章评论