When using this code (Removing Watermark from PDF iTextSharp) to simply read and re-write the content stream for an identical PDF, I get additional operations added to the content stream for this file.
Before Content Stream
q
q
/I0 Do
Q
Q
q
10 0 0 10 0 0 cm
0.1 0 0 0.1 0 0 cm
/QuickPDFXO6d1c5c37 Do
Q
After Content Stream
q
0 -1 1 0 0 1224 cm
q
q
/I0 Do
Q
Q
q
10 0 0 10 0 0 cm
0.1 0 0 0.1 0 0 cm
/QuickPDFXO6d1c5c37 Do
Q
Q
Any idea why this was appended to my content stream?
q
0 -1 1 0 0 1224 cm
....
Q
My Code is similar to the article linked except that I'm trying to remove certain items from the content stream.
XObjectRemover editor = new XObjectRemover();
List<List<PdfContentData>> output = editor.EditPageContent(stamper, pgNumber);
PdfContentByte content = stamper.GetUnderContent(pgNumber);
foreach (List<PdfContentData> bracketList in output)
{
foreach (PdfContentData operandList in bracketList)
{
if (operandList.operandToDelete == false)
{
int index = 0;
foreach (PdfObject op in operandList.pdfOperands)
{
op.ToPdf(content.PdfWriter, content.InternalBuffer);
content.InternalBuffer.Append(operandList.pdfOperands.Count > ++index ? (byte)' ' : (byte)'\n');
}
}
}
}
The PdfContentData class is just a collection of all the content operations with some flagged for delete.
public class PdfContentData
{
public int opNumber { get; set; }
public PdfLiteral pdfOperator { get; set; }
public List<PdfObject> pdfOperands { get; set; }
public bool operandToDelete { get; set; }
public PdfContentData(int opNum, PdfLiteral op, List<PdfObject> ops)
{
this.opNumber = opNum;
this.pdfOperator = op;
this.pdfOperands = ops;
}
public override string ToString()
{
return $"Ops: [{string.Join(",", pdfOperands.Select(p => p.ToString()).ToArray())}] Del: [{operandToDelete}]";
}
}
and XObjectRemover is just a class that is derived from PdfContentStreamEditor, just like TransparentGraphicsRemover in @mkl's example.