0
votes

I'm using PdfFormXObject instead of PdfCanvas to apply background, border, and/or background color to a certain area of a page (mainly because PdfCanvas needs Page to construct, PdfFormXObject doesn't. As my content may last several pages). The problem is that the image is not positioned as expected if coordination (x = 0, y = 0) means bottom-left corner. I also want to position the Canvas to an fixed position but canvas.SetFixedPosition() seems not working. See attached original image and the image to be positioned at {x, y, width, height} = {100f, 100f, 200f, 200f} which should be at the bottom of the page(which is not) and it's also truncated somehow?

  1. code

    public void CreatePDF(string path)
    {
           var writer = new PdfWriter(path);
           var pdf = new PdfDocument(writer);
           var doc = new Document(pdf, PageSize.LETTER);
           doc.SetMargins(18, 18, 18, 18);
           var rect = new Rectangle(100f, 100f, 200f, 200f);
           var temp = new PdfFormXObject(new Rectangle(rect.GetWidth(), rect.GetHeight()));
           var ca = new Canvas(temp, pdf);
           // ca.SetFixedPosition(rect.GetLeft(), rect.GetBottom(), rect.GetWidth());
           var img = new Image(ImageDataFactory.Create(path));
           img.SetFixedPosition(rect.GetLeft(), rect.GetBottom());
           img.ScaleAbsolute(rect.GetWidth(), rect.GetHeight());
           ca.Add(img);
           ca.SetBackgroundColor(ColorConstants.BLUE); // not shown blue bg
           ca.Close();
           doc.Add(new Image(temp));
           doc.Close();
           pdf.Close();
    }
    
  2. original image enter image description here

  3. generated one(wrongly placed at the top) enter image description here

  4. update Here is the working code after mkl's direction. But canvas cannot set border/background color:


       public void CreatePDF(string path)
       {
                var writer = new PdfWriter(path);
                var pdf = new PdfDocument(writer);
                var doc = new Document(pdf, PageSize.LETTER);
                doc.SetMargins(LETTER_MARGIN, LETTER_MARGIN, LETTER_MARGIN, LETTER_MARGIN);
                var rect = new Rectangle(100f, 300f, 200f, 200f);
                var w = Doc.GetPageEffectiveArea(PageSize.LETTER).GetWidth(); //576f
                var h = Doc.GetPageEffectiveArea(PageSize.LETTER).GetHeight();//756f
                var temp = new PdfFormXObject(new Rectangle(w, h));
                var ca = new Canvas(temp, pdf);

                ca.SetFixedPosition(0, 0, 576f);
                ca.SetBorder(new SolidBorder(1f));//not work
                ca.SetBackgroundColor(ColorConstants.BLUE);//not work

                var img = new Image(ImageDataFactory.Create(path));

                img.SetFixedPosition(rect.GetLeft(), rect.GetBottom());
                img.ScaleAbsolute(rect.GetWidth(), rect.GetHeight());
                ca.Add(img);

                ca.Close();
                doc.Add(new Image(temp));

                doc.Close();
                pdf.Close();
     }

  1. Update I added a Div to the ca and set border and background color to the Div. Works perfectly.

TIA

1

1 Answers

0
votes

First, you create a PdfFormXObject using a rectangle you only define width and height for:

var temp = new PdfFormXObject(new Rectangle(rect.GetWidth(), rect.GetHeight()));

Thus, the rectangle has the lower left corner at the origin of the form xobject coordinate system, i.e. lower left is (0,0) and upper right is (200,200).

On this area you position a 200×200 image at (100,100):

img.SetFixedPosition(rect.GetLeft(), rect.GetBottom());
img.ScaleAbsolute(rect.GetWidth(), rect.GetHeight());
ca.Add(img);

So most of the image is outside the xobject, only the lower left quadrant is inside, the one you see in your screenshot.

Then you add this xobject to the document without positioning:

doc.Add(new Image(temp));

Thus, you ask itext to put your 200×200 xobject where it fits given the existing content. So it will be positioned further up than you want.

To fix your issue, therefore, arrange the xobject area and the image position so that the image is in the area, and position the xobject as desired.