How do I programmatically apply redaction annotations using the SDK?

Question:
I am using WebViewer / Adobe Reader to add redaction annotations to a PDF. How can I apply these annotations (and redact the document) in code?

Answer:
The following C# code will iterate through the document and apply all redaction annotations. Note that once the document is redacted, the redaction annotations will also be removed.

static Rect QuadPointToRect(QuadPoint qp)
{
	double rectX1 = Math.Min(Math.Min(Math.Min(qp.p1.x, qp.p2.x), qp.p3.x), qp.p4.x);
	double rectX2 = Math.Max(Math.Max(Math.Max(qp.p1.x, qp.p2.x), qp.p3.x), qp.p4.x);
	double rectY1 = Math.Min(Math.Min(Math.Min(qp.p1.y, qp.p2.y), qp.p3.y), qp.p4.y);
	double rectY2 = Math.Max(Math.Max(Math.Max(qp.p1.y, qp.p2.y), qp.p3.y), qp.p4.y);

	return new Rect(rectX1, rectY1, rectX2, rectY2);
}

static void RedactDoc(PDFDoc doc)
{
	ArrayList rarr = new ArrayList();

	for (PageIterator itr = doc.GetPageIterator(); itr.HasNext(); itr.Next())
	{
		Page page = itr.Current();
		int num_annots = page.GetNumAnnots();
		for (int i = 0; i < num_annots; ++i)
		{
			Annot annot = page.GetAnnot(i);
			if (!annot.IsValid()) continue;
			switch (annot.GetType())
			{
				case Annot.Type.e_Redact:
				{
					var redact = new pdftron.PDF.Annots.Redaction(annot);
					var quadPointCount = redact.GetQuadPointCount();
					if (quadPointCount != 0)
					{
						for (int j=0; j<quadPointCount; j++ )
						{
							var initialRect = QuadPointToRect(redact.GetQuadPoint(j));
							var redaction = new Redactor.Redaction(page.GetIndex(), initialRect, false, redact.GetOverlayText());
							rarr.Add(redaction);
						}
					} else
					{
						var redaction = new Redactor.Redaction(page.GetIndex(), redact.GetRect(), false, redact.GetOverlayText());
						rarr.Add(redaction);
					}
					break;
				}
				default:
				break;
			}
		}
	}

	Redactor.Appearance app = new Redactor.Appearance();
	app.RedactionOverlay = true;
	app.Border = true;
	app.ShowRedactedContentRegions = true;

	Redactor.Redact(doc, rarr, app, false, false);
}

Here is the equivalent Java code:

static void redactDoc(PDFDoc doc) throws PDFNetException {
    ArrayList<Redactor.Redaction> rarr = new ArrayList();


    for (PageIterator itr = doc.getPageIterator(); itr.hasNext();) {
        Page page = itr.next();
        int num_annots = page.getNumAnnots();
        for (int i = 0; i < num_annots; ++i)
        {
            Annot annot = page.getAnnot(i);
            if (!annot.isValid()) continue;
            switch (annot.getType())
            {
                case Annot.e_Redact:
                {
                    var redact = new Redaction(annot);
                    var quadPointCount = redact.getQuadPointCount();
                    if (quadPointCount != 0)
                    {
                        for (int j=0; j<quadPointCount; j++ )
                        {
                            var initialRect = quadPointToRect(redact.getQuadPoint(j));
                            var redaction = new Redactor.Redaction(page.getIndex(), initialRect, false, redact.getOverlayText());
                            rarr.add(redaction);
                        }
                    } else
                    {
                        var redaction = new Redactor.Redaction(page.getIndex(), redact.getRect(), false, redact.getOverlayText());
                        rarr.add(redaction);
                    }
                    break;
                }
                default:
                    break;
            }
        }
    }

    Redactor.Appearance app = new Redactor.Appearance();
    app.redactionOverlay = true;
    app.border = true;
    app.showRedactedContentRegions = true;

    Redactor.Redaction[] redact_array = new Redactor.Redaction[rarr.size()];

    for (int i = 0; i < redact_array.length; i++) {
        redact_array[i] = rarr.get(i);
    }

    Redactor.redact(doc, redact_array, app, false, false);
}

private static Rect quadPointToRect(QuadPoint qp) throws PDFNetException {
    double rectX1 = Math.min(Math.min(Math.min(qp.p1.x, qp.p2.x), qp.p3.x), qp.p4.x);
    double rectX2 = Math.max(Math.max(Math.max(qp.p1.x, qp.p2.x), qp.p3.x), qp.p4.x);
    double rectY1 = Math.min(Math.min(Math.min(qp.p1.y, qp.p2.y), qp.p3.y), qp.p4.y);
    double rectY2 = Math.max(Math.max(Math.max(qp.p1.y, qp.p2.y), qp.p3.y), qp.p4.y);

    return new Rect(rectX1, rectY1, rectX2, rectY2);
}