0

I am facing a problem while adding a watermark at the center of each page of a pdf file.

What i have tried so far :

      PdfStamper inputPdfStamper = null;
                try {
                    PdfReader inputPdfReader = new PdfReader(new FileInputStream(input));
                    inputPdfStamper = new PdfStamper(inputPdfReader, new FileOutputStream(input));
                    Font font = new Font(fontFamily, fontSize, fontStyle, color);
                    for (int pageNumber = 1 ;pageNumber <=inputPdfStamper.getReader().getNumberOfPages() ; pageNumber++){
                        if(isWatermarkAbove){                           
                      ColumnText.showTextAligned(inputPdfStamper.getOverContent(pageNumber), Element.ALIGN_CENTER, new Phrase(watermark, font),  inputPdfReader.getPageSize(pageNumber).getRight()/2, inputPdfReader.getPageSize(pageNumber).getTop()/2, 45);
     // Updated Code 
    // ColumnText.showTextAligned(inputPdfStamper.getUnderContent(pageNumber), Element.ALIGN_CENTER, new Phrase(watermark, font), inputPdfReader.getCropBox(pageNumber).getLeft()/2, inputPdfReader.getCropBox(pageNumber).getBottom()/2, 45);
                        }else{
                            ColumnText.showTextAligned(inputPdfStamper.getUnderContent(pageNumber), Element.ALIGN_CENTER, new Phrase(watermark, font), inputPdfReader.getPageSize(pageNumber).getRight()/2, inputPdfReader.getPageSize(pageNumber).getTop()/2, 45);
                        }
                    }
                    inputPdfStamper.close();
                } catch (Exception e){
                    throw new RuntimeException(e);
                }finally {
                    if (inputPdfStamper!=null) {
                        try {
                            inputPdfStamper.close();
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

Issue:

The above code works fine for pdf file which has same dimensions(height and width) for all the pages. But when I provide pdf pages with different dimensions , watermark is placing in different positions not in the center.

What I Known :

ColumnText.showTextAligned(inputPdfStamper.getUnderContent(pageNumber), Element.ALIGN_CENTER, new Phrase(watermark, font), inputPdfReader.getPageSize(pageNumber).getRight()/2, inputPdfReader.getPageSize(pageNumber).getTop()/2, 45)

After I debug and evaluate the above code I am getting the same page size value for all the pages of the pdf which are in different dimensions.

inputPdfReader.getPageSize(pageNumber).getRight()

gives the same page size value for all the pages of the pdf. and also inputPdfReader.getPageSize(pageNumber).getTop() gives the same value for all the pages which are in different dimensions(hieght and width)

Question :

How to get the page size of each pages of the pdf file which are in different dimensions

ravikumar
  • 893
  • 1
  • 8
  • 12
  • 1
    You only mention `inputPdfReader.getPageSize(pageNumber).getRight()` and `inputPdfReader.getPageSize(pageNumber).getTop()` --- have you also checked `...getLeft()` and `...getBorrom()`? Your code implicitly assumes that the bottom left coordinate values are (0,0), but that is only true for most PDFs, but not for all. – mkl Sep 17 '14 at 07:29
  • @mkl thanks for the response, the issue is inputPdfReader.getPageSize(pageNumber).getRight() gives the same size for all the pages even if the page is of different size – ravikumar Sep 17 '14 at 07:46
  • 1
    Moreover, `getPageSize()` gives you the `Rectangle` object that corresponds with the `/MediaBox`, but some page dictionaries also have a `/CropBox` entry. Did you check the `getCropBox()` method? The crop box defines the visible area of the page. The crop box should always be smaller than the mediabox. – Bruno Lowagie Sep 17 '14 at 07:47
  • 1
    It is perfectly normal that `getRight()` is identical for pages with a different width. Either the `getLeft()` value is different, or you are ignoring the fact that there's a crop box. – Bruno Lowagie Sep 17 '14 at 07:48
  • @BrunoLowagie yes i have tried by calling getCropBox() but the watermark was adding at the center for some pages and i found the same response with getPageSize() as well.... yes what u r saying is correct crop box was smaller than mediabox (I found it when i debug the code) but the end result was the same for those two cases – ravikumar Sep 17 '14 at 07:53
  • Your comment is very unclear. Adding a Watermark based on the dimensions of the crop box should be a piece of cake. Show us what you've tried (your code snippet in your question still mentions `getPageSize()`). – Bruno Lowagie Sep 17 '14 at 07:55
  • Did you pass your Math tests at school? Your method to calculate the middle of the page is all wrong. – Bruno Lowagie Sep 17 '14 at 08:25
  • @ravikumar To calculate the page center you have to use the mean values of `getLeft` and `getRight` as x coordinate and the mean value of `getBottom` and `getTop` as y coordinate. And of course use the crop box. – mkl Sep 17 '14 at 08:35
  • @mkl thanks for the response i will implement in my code.. – ravikumar Sep 17 '14 at 08:37

1 Answers1

1

This is not an iText problem. This is a Math problem.

If you have a coordinate (x1, y1) representing the lower-left corner of a rectangle, and a coordinate (x2, y2) representing the upper-right corner of a rectangle, you can calculate the coordinate of the middle of the rectangle like this:

((x1 + x2) / 2, (y1 + y2) / 2)

If you don't understand this formula, think about this:

The width of the rectangle is (x2 - x1).

Half the width equals (x2 - x1) / 2.

The coordinate you need to get the middle is x1 + (x2 - x1) / 2

Or: x1 - x2 / 2 - x1 / 2

Or x1 / 2 + x2 / 2

Or (x1 + x2) / 2

In your code sample, you have tried:

inputPdfReader.getCropBox(pageNumber).getLeft()/2
inputPdfReader.getPageSize(pageNumber).getRight()/2

This corresponds with:

x1 / 2
x2 / 2

This doesn't make any sense! This is what you need:

Rectangle crop = inpitPdfReader.getCropBox(pageNumber);
float x = (crop.getLeft() + crop.getRight()) / 2;
float y = (crop.getBottom() + crop.getTop()) / 2;

Your question doesn't qualify as an iText-related question. This is elementary Math.

Obviously: if crop equals null, then there is no crop box and you need to use the value of the media box.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thanks for the answer. I come across this question when i debug my code, for the first page of a pdf crop.getRight() gives me 842.0 and agian for the rest of the pages i m recieving the same value even the size of those pages are different. – ravikumar Sep 17 '14 at 09:51
  • 842 is the height of an A4 page in portrait. If `getRight()` returns 842, then your page is rotated by 90 degrees. You should ask the page for its rotation too. – Bruno Lowagie Sep 17 '14 at 09:57