我设法创建了一段从 PDF 文件中提取嵌入字体的 C# 代码。我正在使用嵌入了 TrueType 字体的文档对其进行测试。
问题是当我将字体字节写入文件时,我无法用任何字体查看器打开它,因为它似乎已损坏。
有趣的是,代码似乎相当不错,因为执行MuPDF mutool.exe extract
我得到了完全相同的文件和相同的结果(损坏的 .ttf 文件)。
这是代码(对不起,它很大,但到目前为止我没有找到更短的方法来实现这一点):
public void ExtractFonts(PdfReader reader, PdfParserDocument document)
{
foreach (var fontData in BaseFont.GetDocumentFonts(reader))
{
// Get font name and indirect reference
var name = (string)fontData[0];
var reference = (PRIndirectReference)fontData[1];
// Get font bytes from PDF
var XrefIndex = Convert.ToInt32(reference.Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
var fontDictionary = (PdfDictionary)reader.GetPdfObject(XrefIndex);
var fontDescriptor = fontDictionary.GetAsDict(PdfName.FONTDESCRIPTOR);
PRIndirectReference fontBytesReference = null;
if (fontDescriptor != null)
{
if (fontDescriptor.Get(PdfName.FONTFILE) != null)
{
fontBytesReference = (PRIndirectReference)fontDescriptor.Get(PdfName.FONTFILE);
}
else if (fontDescriptor.Get(PdfName.FONTFILE2) != null)
{
fontBytesReference = (PRIndirectReference)fontDescriptor.Get(PdfName.FONTFILE2);
}
else if (fontDescriptor.Get(PdfName.FONTFILE3) != null)
{
fontBytesReference = (PRIndirectReference)fontDescriptor.Get(PdfName.FONTFILE3);
}
}
// Only add embedded fonts
if (fontBytesReference != null)
{
var fontBytesReferenceIndex = Convert.ToInt32(fontBytesReference.Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
var pdfObject = reader.GetPdfObject(fontBytesReferenceIndex);
var pdfStream = (PdfStream)pdfObject;
var bytes = PdfReader.FlateDecode(PdfReader.GetStreamBytesRaw((PRStream)pdfStream));
// Write to file
using (var file = File.OpenWrite(name + ".ttf"))
{
file.Write(bytes, 0, bytes.Length);
}
}
}
}