Search code examples
c#.net-coreitextitext7

How can I rotate an image before adding it to a PDF?


I'm trying to add multiple random dynamic watermark images to each page of my PDF. These generated images should be rotated 45 degrees. When I add an image to the PDF, even after specifying the rotation, the image still appears flat. Any ideas why the rotation is not applied? I'm using Itext7

iText.Kernel.Geom.Rectangle pagesize;
Image img = DrawText(watermark);
ImageData imageData = ImageDataFactory.CreatePng(ImageToByteArray(img));

float x, y;
// loop over every page
for (int i = 1; i <= n; i++)
{
    int watermarksPerPage = GetRandomNumber(1, MAX_WATERMARKS_PER_PAGE);
    PdfPage page = doc.GetPage(i);
    pagesize = page.GetPageSizeWithRotation();
    PdfCanvas canvas = new PdfCanvas(page);

    x = (pagesize.GetLeft() + pagesize.GetRight());
    y = (pagesize.GetRight() + pagesize.GetBottom());

    canvas.SetExtGState(gs1);

    int boundaryWidth = (int)(x * INVISIBLE_BOUNDARY_PERCENT);
    int boundaryHeight = (int)(y * INVISIBLE_BOUNDARY_PERCENT);

    for (int m = 0; m <= watermarksPerPage; m++)
    {
        //create an invisble boudary that the watermark should not cross using x% of width      
        float newx = GetRandomNumber(0, (int)x - boundaryHeight);
        float newy = GetRandomNumber(0, (int)y - boundaryWidth);
        imageData.SetRotation(ROTATION);
        canvas.AddImage(imageData, newx, newy, false);
    }
}

Solution

  • ImageData.SetRotation does not set the rotation value used whenever this ImageData instance is rendered by iText, it merely overwrites the metadata of the image indicating how the image should be rendered to appear upright. As far as I can see, the corresponding GetRotation is not called at all currently by iText code, so your rotation value is ignored.

    Instead of setting that image data rotation value, therefore, simply rotate the canvas before inserting the image, e.g. like this:

    canvas.SaveState();
    canvas.ConcatMatrix(AffineTransform.GetRotateInstance(Math.PI / 4, x, y));
    canvas.AddImage(imageData, x - imageData.GetWidth() / 2, y - imageData.GetHeight() / 2, false);
    canvas.RestoreState();