Search code examples
c#pdfitext

Insert image in place of sticky notes in pdf by iTextSharp incorrect


I am trying to insert an image in place of sticky notes on a pdf. However, I am having the problem that the sticky notes position is taken ok but when the image is inserted, it is not right there.

here is my code

  public void LoadData()
    {
        Stream inputPdfStream = new FileStream(txtFilePDF.Text, FileMode.Open, FileAccess.Read, FileShare.Read);
        Stream outputPdfStream = new FileStream("result.pdf", FileMode.Create, FileAccess.Write, FileShare.None);

        reader = new PdfReader(inputPdfStream);
        stamper = new PdfStamper(reader, outputPdfStream);
       

        //loop find sticky notes in page and replace by image
        for (int x = 1; x <= reader.NumberOfPages; x++) // i =1 page 1
        {
            PdfDictionary page = reader.GetPageN(x);
            pdfContentByte = stamper.GetOverContent(x);
            PdfArray annots = page.GetAsArray(PdfName.ANNOTS);

            //replace image in place of sticky notes
            try
            {
                for (int i = 0; i < annots.Count(); i++)
                {
                    PdfDictionary sticky = annots.GetAsDict(i);
                    PdfArray stickyRect = sticky.GetAsArray(PdfName.RECT);
                    //get position sticky notes
                    stickyRectangle = new PdfRectangle(
                        stickyRect.GetAsNumber(0).FloatValue, stickyRect.GetAsNumber(1).FloatValue,
                        stickyRect.GetAsNumber(2).FloatValue, stickyRect.GetAsNumber(3).FloatValue
                    );
                    
                  
                    string Content = "";
                    try
                    {
                        Content = sticky.GetAsString(PdfName.CONTENTS).ToString();
                    }
                    catch
                    {
                        Content = "";
                    }

                    if (Content.ToString().Trim().ToLower() == "trinhky")
                    {
                        //get image
                        GetHinhAnh(txtUserTrinhKy.Text);
                    }
                  




                }

            }
            catch { }

           
        }
        //remove all sticky notes in output pdf
       // reader.RemoveAnnotations();
        //end process
        stamper.Close();
        reader.Close();
        inputPdfStream.Close();
        outputPdfStream.Close();

   
    }

    public void GetHinhAnh(string UserName)
    {
        try
        {
            //get image
            System.Drawing.Image chuky = ((System.Drawing.Image)(Properties.Resources.ResourceManager.GetObject(UserName)));
            //covert to  iTextSharp image
            iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(chuky, iTextSharp.text.BaseColor.WHITE, false);

            image.ScaleAbsolute(100, 80);
            image.SetAbsolutePosition( stickyRectangle.Left,stickyRectangle.Bottom); // set position sticky note to image
            pdfContentByte.AddImage(image);
        }
        catch { }
    }
  

how to insert image in the correct position of sticky notes in pdf file? i would greatly appreciate if someone can give me a solution for this case.

now, I try the following method

stamper.RotateContents=false;

now it got the correct position but the added image rotated due to the pdf page (demo file is rotating 270). what should i do to not rotate the new image?


Solution

  • There are a few details here resulting in the wrong position.

    Rotated Page

    The page is rotated by 270°. In such a situation iText transforms the coordinate system for content stream additions. On the other hand they are not transformed for your annotation position retrieval. Thus, they don't match at all.

    You already found out yourself that you can make iText use the coordinates as they are and not transform them by executing

    stamper.RotateContents=false;
    

    But this also causes the added image not to be rotated in the static content and, therefore, appear toppled on the rotated page.

    To also rotate the image to match the later page rotation, you can do

    image.RotationDegrees = reader.GetPageRotation(x);
    

    (You additionally might have to switch the arguments of your image.ScaleAbsolute call in case of 90° and 270° rotations to prevent distortions.)

    NoRotate Flag on Annotation

    Furthermore, the annotation in your example document has the NoRotate flag set. This effect of this flag is illustrated as:

    Figure 78 — Coordinate adjustment with the NoRotate flag

    (ISO 32000-2 Section 12.5.3 — Annotation flags)

    Thus, when the PDF viewer rotates the page by 270°, the annotation is not rotated with the text and the Rect value you use does not map exactly to the static content. As the annotation is very small, though, the resulting offset is small, too.

    Lower Left Is Not Lower Left Anymore

    An effect of the rotation also is that the lower left corner of the annotation (which was the fixed point in your unrotated use case) after page rotation is not the lower left anymore.

    In case of your example document the rotation by 270° results in the lower right corner of the annotation to be the fixed point and your image growing up and to the left...