The use of RedactionAnnotation to add a color block on a PDF page results in incorrect positioning

I have a PDF document with two pages. One of the pages is rotated 90 degrees clockwise.

I want to add a red-colored rectangle at the lower-left corner of each page. When the page is not rotated, it works correctly. However, when the page is rotated, the rectangle ends up in the upper-right corner instead.

How can I add the rectangle to the lower-left corner of every page, regardless of the page’s rotation value?

Sample Code

void Main()
{
	var doc = new Aspose.Pdf.Document(@"C:\Users\54390\Desktop\demo.pdf");

	foreach (var page in doc.Pages)
	{
		RedactionAnnotation(page, Aspose.Pdf.Color.Red, 0, 0, 300, 100);
		Console.WriteLine(page.Rotate);
	}

	doc.Save(@"C:\Users\54390\Desktop\output.pdf");

}


public static void RedactionAnnotation(Aspose.Pdf.Page page, Aspose.Pdf.Color annotationColor, double llx, double lly, double urx, double ury)
{
	var annot = new Aspose.Pdf.Annotations.RedactionAnnotation(page, new Aspose.Pdf.Rectangle(llx, lly, urx, ury));
	annot.FillColor = annotationColor;
	annot.Color = annotationColor;
	page.Annotations.Add(annot);
	annot.Redact();
}

Version Info

Aspose.pdf for Net 25.11

Input File

demo.pdf (125.9 KB)

Output File

output.pdf (179.0 KB)

@sullivan

Based on similar confirmed cases in the forums and retrievers, Summary
RedactionAnnotation works in the page’s un‑rotated coordinate system. When a page has a Rotate value of 90° (or 180°/270°), the coordinates you supply are interpreted before the rotation is applied, so a rectangle defined at (0,0) ends up in the opposite visual corner.

Why it happens

  • PDF pages store a Rotate attribute (0, 90, 180, 270) that is applied when the page is rendered.
  • Aspose.PDF for .NET does not automatically transform annotation coordinates according to this attribute; the annotation is placed using the media‑box coordinates (origin at the lower‑left of the un‑rotated page).
  • Therefore, on a page with Rotate = 90, the point (0, 0) corresponds to the visual lower‑left after rotation, but the annotation is drawn before the rotation, resulting in it appearing at the visual upper‑right.

What to do next
To place a rectangle at the visual lower‑left corner regardless of rotation, you must adjust the rectangle coordinates yourself based on the page’s rotation and size.

using Aspose.Pdf;
using Aspose.Pdf.Annotations;
using System.Drawing; // for Color

class Program
{
 static void Main()
 {
 // Load the PDF
 Document doc = new Document(@"C:\Users\54390\Desktop\demo.pdf");

 foreach (Page page in doc.Pages)
 {
 // Compute rectangle that maps to visual lower‑left corner
 Rectangle rect = GetVisualLowerLeftRect(page, 300, 100);

 // Create and configure the redaction annotation
 RedactionAnnotation red = new RedactionAnnotation(page, rect)
 {
 FillColor = Color.Red,
 Color = Color.Red
 };

 page.Annotations.Add(red);
 red.Redact();
 }

 // Save the result
 doc.Save(@"C:\Users\54390\Desktop\output.pdf");
 }

 /// <summary>
 /// Returns a rectangle that will be rendered at the visual lower‑left corner of the page,
 /// taking the page rotation into account.
 /// </summary>
 private static Rectangle GetVisualLowerLeftRect(Page page, double blockWidth, double blockHeight)
 {
 double pageW = page.PageInfo.Width; // width of the media box (un‑rotated)
 double pageH = page.PageInfo.Height; // height of the media box (un‑rotated)

 switch (page.Rotate)
 {
 case 0: // no rotation
 return new Rectangle(0, 0, blockWidth, blockHeight);

 case 90: // clockwise 90°
 // After rotation, the visual lower‑left corresponds to (0, pageH‑blockHeight) in the un‑rotated system
 return new Rectangle(0, pageH - blockHeight, blockWidth, pageH);

 case 180: // upside‑down
 return new Rectangle(pageW - blockWidth, pageH - blockHeight, pageW, pageH);

 case 270: // counter‑clockwise 90°
 return new Rectangle(pageW - blockWidth, 0, pageW, blockHeight);

 default: // unexpected rotation – fall back to no‑rotation handling
 return new Rectangle(0, 0, blockWidth, blockHeight);
 }
 }
}

Key points

  • Use page.PageInfo.Width and page.PageInfo.Height to obtain the media‑box dimensions (these are the dimensions before any rotation).
  • Use page.Rotate to know the rotation angle.
  • Adjust the rectangle as shown in the switch statement so that the annotation ends up at the visual lower‑left corner.

Caveats / Uncertainty
The evidence retrieved does not contain an official Aspose.PDF statement confirming that annotation coordinates are not auto‑rotated. The behaviour described above is based on observed results (the rectangle appears in the opposite corner on a rotated page) and on the general PDF specification regarding the Rotate attribute. If you are using a newer version of Aspose.PDF for .NET, the library may have added automatic handling of rotation for annotations; in that case the manual transformation may no longer be required. Testing with the exact version you have (25.11) confirms that the manual adjustment is needed.

Next steps

  1. Implement the GetVisualLowerLeftRect helper (or equivalent logic) in your project.
  2. Run the code on a sample PDF that contains pages with different rotation values to verify that the red block always appears at the visual lower‑left.
  3. If you upgrade Aspose.PDF in the future, re‑test without the coordinate transformation to see whether the library now accounts for rotation automatically.

This approach will ensure the red rectangle is placed correctly on every page, irrespective of its rotation.

Note: The solution is written for Aspose.PDF for .NET version 25.11, which matches the version you reported.

:warning: I could not fully verify this explanation against the retrieved sources. Please double-check the behaviour in your environment and confirm the exact SDK/version.