使用iTextSharp删除PDF中的对象并保存

时间:2016-08-31 13:37:21

标签: pdf itext

这是OCR出错的情况。我需要从PDF中删除隐藏文本,并且我很难弄清楚如何去做。

隐藏文本位于一个名为/ QuickPDFsomething的区域中,该区域位于/ XObject字典中,位于页面/资源字典中。

iRups CS Viewer

我已经尝试过这两件事但两件事都没有用,所以我显然做错了。

选项1 - 杀死obj - PDF无法在Acrobat中打开并声明,'此页面上存在错误。 Acrobat可能无法正确显示页面'但看起来还不错。 Pitstop与“关键解析器失败:缺少XObject资源'。

PdfReader.KillIndirect(obj);
oPdfFile.GetPdfReader().RemoveUnusedObjects();
var stamper = new PdfStamper(oPdfFile.GetPdfReader(), new FileStream(@"C:\temp.pdf", FileMode.Create));
stamper.Close();

选项2 - CleanupProcessor - 引发关于'的异常无法从具有索引像素格式的图像创建图形对象。

var stamper = new PdfStamper(oPdfFile.GetPdfReader(), new FileStream(@"C:\temp.pdf", FileMode.Create));
var cleanupLocations = new List<PdfCleanUpLocation>();
var pageRect = oPdfFile.GetPdfReader().GetCropBox(1);
cleanupLocations.Add(new PdfCleanUpLocation(1, pageRect));
PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanupLocations, stamper);
cleaner.CleanUp();
stamper.Close();

我想删除/ QuickPDF对象(此图片中为41 0 R),并将其从使用/ QuickPDF Do调用它的内容流中删除。

不幸的是我无法提供PDF。

有关如何执行此操作的任何提示?

1 个答案:

答案 0 :(得分:0)

我不想回答我自己的问题,但我想分享我发现的解决方案以防其他人需要它。

在玩了几天之后,我发现上面的选项1确实会删除该对象,而我从PitStop获得的异常是因为内容流引用了/ QuickPDF XObject。

所以我尝试在这里跟踪@ mkl的解决方案Removing Watermark from PDF iTextSharp,但它不断将不需要的数据放入旋转我的PDF的内容流中。

然后我在这里找到了@Chris的解决方案Removing Watermark from a PDF using iTextSharp,虽然我不确定这个解决方案的稳定性,但它似乎有效。

这是我从内容流中删除/ QuickPDF的解决方案:

int numPages = oPdfFile.GetPdfReader().NumberOfPages;
int pgNumber = 1;

PdfDictionary page = oPdfFile.GetPdfReader().GetPageN(pgNumber);
PdfArray contentarray = page.GetAsArray(PdfName.CONTENTS);
PRStream stream;
string content;
if (contentarray != null)
{
    //Loop through content
    for (int j = 0; j < contentarray.Size; j++)
    {
        stream = (PRStream)contentarray.GetAsStream(j);
        content = Encoding.ASCII.GetString(PdfReader.GetStreamBytes(stream));
        string[] tokens = content.Split('\n');
        for (int i = 0; i< tokens.Length; i++)
        {
            if (tokens[i].Contains("/QuickPDF"))
            {
                tokens[i] = string.Empty;
            }
        }

        string outstr = string.Join("\n", tokens.Select(p => p).ToArray());
        byte[] outbytes = Encoding.ASCII.GetBytes(outstr);
        stream.SetData(outbytes);
    }
}