【发布时间】:2013-05-02 17:13:53
【问题描述】:
我正在尝试从 pdf 文件中提取一些字体流(合法性不是问题,因为我的公司已经支付了以原始方式显示这些文档的权利 - 这需要进行转换,这需要提取字体)。
现在,我一直在使用 MUTool - 但它也提取 pdf 中的图像,没有绕过它们的方法,其中一些包含成千上万的图像。所以,我上网寻求答案,并得出以下解决方案:
我将所有字体放入字体字典,然后尝试使用以下代码将它们转换为 PdfStreams(用于 flatedecode 然后写入文件):
PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject((PdfObject)cItem.pObj);
PdfName type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));
try
{
int xrefIdx = ((PRIndirectReference)((PdfObject)cItem.pObj)).Number;
PdfObject pdfObj = (PdfObject)reader.GetPdfObject(xrefIdx);
PdfStream str = (PdfStream)(pdfObj);
byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)str);
}
catch { }
但是,当我到达 PdfStream str = (PdfStream)(pdfObj); 我收到以下错误:
Unable to cast object of type 'iTextSharp.text.pdf.PdfDictionary'
to type 'iTextSharp.text.pdf.PdfStream'.
现在,我知道 PdfDictionary 派生自(扩展)PdfObject,所以我不确定我在这里做错了什么。有人请帮忙 - 我需要有关修补此代码的建议,或者如果完全不正确,则需要正确提取流的代码或指向具有所述代码的位置。
谢谢。
编辑 我修改后的代码在这里:
public static void GetStreams(PdfReader pdf)
{
int page_count = pdf.NumberOfPages;
for (int i = 1; i <= page_count; i++)
{
PdfDictionary pg = pdf.GetPageN(i);
PdfDictionary fObj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.FONT));
if (fObj != null)
{
foreach (PdfName name in fObj.Keys)
{
PdfObject obj = fObj.Get(name);
if (obj.IsIndirect())
{
PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
PdfName type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));
int xrefIdx = ((PRIndirectReference)obj).Number;
PdfObject pdfObj = pdf.GetPdfObject(xrefIdx);
if (pdfObj == null && pdfObj.IsStream())
{
PdfStream str = (PdfStream)(pdfObj);
byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)str);
}
}
}
}
}
}
但是,我仍然收到相同的错误 - 所以我假设这是一种不正确的检索字体流的方法。同一个文档已经使用 muTool 成功提取了字体 - 所以我知道问题出在我身上,而不是 pdf。
【问题讨论】:
-
好吧,您的代码确实没有提示您检查的对象是否确实是流。请详细说明。
-
显然我没有得到流对象(只是字典),我还没有找到关于如何正确抓取字体流的好答案。
-
你有没有做过一些调试并确定了pdfObj的实际类?您是否还按照布鲁诺的提示将演员表移至 PdfStream 以支持 PRStream 的演员表?您发布的代码首先转换为 PdfStream,然后转换为 PRStream...
-
是的,从转换为 PdfStream 到转换为 PRStream 的更改是根据 Bruno 的建议。我还使用了他建议的代码示例(sorta)来提取流。现在,当我尝试使用 PdfReader.FlateDecode() 时出现错误“缓冲区不能为空”,有什么想法吗?
-
缓冲区不能为空错误已得到纠正——当然是我的错误。我使用 PRStream.GetBytes() 而不是 PdfReader.GetStreamBytes(PRStream),当然我的 byte[] 是空的。
标签: pdf fonts stream itextsharp itext