2

Using the iText5 PDF library, I am able to read bookmarks exist in PDF. Now I want to change the zoom level of bookmarks (Inherit zoom) in existing PDF using iText. Is it possible using the iText PDF library, and how?

I have attached a screenshot. enter image description here

This is the code I am using to change the bookmark zoom level (as per @lowagie comment):

public void changeList(List<HashMap<String, Object>> list) {
        for (HashMap<String, Object> entry : list) {
            for (String key : entry.keySet()) {
                System.out.println(key);

                if ("Kids".equals(key)) {
                    Object o = entry.get(key);
                    changeList((List<HashMap<String, Object>>) o);
                } else if ("Page".equals(key)) {
                    String dest = (String) entry.get(key);
                    entry.put("Page", dest.replaceAll("Fit", "XYZ 30 100 0"));
                }
            }
        }
    }

Bookmark Tree Structure : enter image description here

Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
Butani Vijay
  • 4,181
  • 2
  • 29
  • 61

2 Answers2

4

Please take a look at my answer to the following question: Set inherit Zoom(action property) to bookmark in the pdf file

In that answer, I read bookmarks using the SimpleBookmark object. That's probably the same way you are reading bookmarks. The result is a List of HashMap objects that represents an outline tree. I use a recursive method to find all the "Page" entries.

These page entries contain a destination, for instance Fit, FitH, XYZ,... You need to change all these references into XYZ references of which you set the zoom factor to 0. A zoom factor 0 is the equivalent of 'Inherit Zoom'.

In my answer to Set inherit Zoom(action property) to bookmark in the pdf file I had this code:

public void changeList(List<HashMap<String, Object>> list) {
    for (HashMap<String, Object> entry : list) {
        for (String key : entry.keySet()) {
            if ("Kids".equals(key)) {
                Object o = entry.get(key);
                changeList((List<HashMap<String, Object>>)o);
            }
            else if ("Page".equals(key)) {
                String dest = (String)entry.get(key);
                entry.put("Page", dest.replaceAll("Fit", "FitV 60"));
            }
        }
    }
}

It's obvious that you can replace any existing "Page" action by a completely new action. For instance:

entry.put("Page", "XYZ 30 100 0");

Now you'll jump to the coordinate 30 100 on the page with an inherited zoom factor. If you want to zoom in on another part, for instance a location that corresponds more or less with the original location, you need to examine the coordinates that followed the FitR in your original PDF. There are 4: the lower-left x, lower-left y, upper-right x and upper-right y coordinate. You could parse the string with the original destination for those values and reuse two of these coordinates as your X and Y values in the XYZ destination.

The X Y coordinate passed with the XYZ destination is the coordinate of the top-left corner. For instance, if you have FitR -3 234 486 627, then you zoom in on a rectangle with coordinates llx = -3, lly = 234, urx = 486 and ury = 627 (ll refers to lower-left; ur refers to upper-right). The top left corner is llx,ury or in your case x = -3 and y = 627. In short: in this case, you'd need "XYZ -3 627 0".

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Zoom level in some bookmark is Custom, how can i make it inherit zoom? – Butani Vijay Jun 16 '14 at 09:08
  • If i open my pdf file in notpad++ editor, i found **FitR**( before changing bookmark level) – Butani Vijay Jun 16 '14 at 09:22
  • As per your suggestion, i have tried code(added in question)- but unable to work in some file( specially when zoom level is custom). – Butani Vijay Jun 16 '14 at 09:46
  • I want to see that PDF, so that I can prove that either my answer is correct, or the PDF is not what you pretend it to be. – Bruno Lowagie Jun 16 '14 at 14:15
  • Note that `FitR` refers to "fit rectangle", which means you don't define a `z` value as a zoom factor but a rectangle to zoom into. If you want "Inherit zoom", you need `XYZ` followed by 3 parameters: an x value, a y value and 0 for the zoom value. You're not telling me anywhere if you understood this. You're not telling me what you found *after* changing the bookmarks. – Bruno Lowagie Jun 16 '14 at 14:23
  • Your answer is correct. but if the bookmark property is custom unable to make it inherit zoom in some case. or can i change FitR to XYZ. – Butani Vijay Jun 17 '14 at 04:02
  • Can you provide your email id ,so i can send you PDF file. – Butani Vijay Jun 17 '14 at 04:05
  • If i change bookmark i found nothing in bookmark property(action), no zoom level. – Butani Vijay Jun 17 '14 at 04:07
  • It should be obvious that not every bookmark has a zoom level. Zoom levels can only be defined for XYZ destinations. Did you study any of the documents that are available? – Bruno Lowagie Jun 17 '14 at 04:10
  • That was implied in my answer. Note that people on SO are here to answer technical questions, not to do other people's homework. If I had just posted the code that solved *a specific problem*, this wouldn't have been interesting for other users. On SO, *generic answers* are preferred. As my answer is correct, you should accept it. Note that your colleague has succeeded where you fail: http://stackoverflow.com/questions/24217657/set-inherit-zoomaction-property-to-bookmark-in-the-pdf-file#comment37454562_24217767 – Bruno Lowagie Jun 17 '14 at 04:14
  • Also: (1) asking people's personal e-mail is **not done on StackOverflow**, and (2) it's hard to believe somebody wouldn't be able to find my e-mail ;-) – Bruno Lowagie Jun 17 '14 at 04:17
  • if i use like entry.put("Page", dest.replaceAll("FitR", "XYZ 30 100 0"));. it set inherit zoom but when i click on bookmark unable to reach at desired location. – Butani Vijay Jun 17 '14 at 04:25
  • When you pick "XYZ 30 100 0", you tell the PDF that your desired location has the coordinate 30 100. Are you saying that 30 100 is **not** your desired location? If so, why don't you define your desired location? – Bruno Lowagie Jun 17 '14 at 04:29
  • Can i get bookmark top,left value and set it with XYZ. – Butani Vijay Jun 17 '14 at 04:34
  • I updated my answer explaining that you can find those coordinates right after the `"FitR"` in your original bookmarks. You have the coordinate of the lower-left and upper-right coordinate of the rectangle that was used as zoom area. Please accept the answer or I'll stop giving you advise. – Bruno Lowagie Jun 17 '14 at 04:36
  • I found Dest value like FitR -3 234 486 627. which value i have to use as x and y so destination will not get disturb?? sorry but last. – Butani Vijay Jun 17 '14 at 04:53
  • The X Y coordinate passed with the XYZ destination is the coordinate of the top-left corner. If you currently zoom in on llx = -3, lly = 234, urx = 486 and ury = 627, the top left corner is llx,ury or in your case x = -3 and y = 627. In short: you need "XYZ -3 627 0". – Bruno Lowagie Jun 17 '14 at 05:13
  • I have one more problem regarding hyper link....http://stackoverflow.com/questions/24260323/itext-change-zoom-level-of-all-hyper-link-to-inherit-zoom-in-existing-pdf – Butani Vijay Jun 17 '14 at 09:35
1

Unfortunately I can't help you out if you must do it with iText. But if you just want to change the zoom level of your bookmarks, you can also use the PDF Clown library, which I personally like a lot (especially when it comes to API design compared with iText).

Check out this small Java application I wrote, that does exactly what you want. The Wizard class gives you an overview on how to the change the zoom level. Basically you can achieve this with:

private void modifyBookmarks(Bookmarks bookmarks) {
    for (Bookmark bm : bookmarks) {
        if (!bm.getBookmarks().isEmpty()) {
            modifyBookmarks(bm.getBookmarks());
        }

        if (bm.getTarget() instanceof GoToDestination<?>) {
            Destination dest = ((GoToDestination<?>) 
                    bm.getTarget()).getDestination();
            dest.setMode(ModeEnum.XYZ);
            dest.setZoom(0.0);
        }
    }
}
beatngu13
  • 7,201
  • 6
  • 37
  • 66
  • Yes, both (the tool and the library). Check out [org.bitbucket.beatngu13.pdfbookmarkwizard.core.Wizard](https://bitbucket.org/beatngu13/pdfbookmarkwizard/src/0b30973ce9c135809c9bdbffb61e1bb577c0a942/PDFBookmarkWizard/src/org/bitbucket/beatngu13/pdfbookmarkwizard/core/Wizard.java?at=master) to see how to apply various zoom levels to your bookmarks. – beatngu13 Apr 01 '14 at 07:45
  • Actually my project build with java 1.5,does it possible in my project? because library compile with java 6... – Butani Vijay Apr 01 '14 at 07:49
  • I have try using old version of library, but no method to set zoom level – Butani Vijay Apr 01 '14 at 07:53
  • There is a [help forum](http://sourceforge.net/p/clown/discussion/607163/) where you can ask library-specific questions like this. – beatngu13 Apr 01 '14 at 11:53
  • Thanks @beatngu , can i change magnification using this library – Butani Vijay Apr 01 '14 at 12:50
  • 1
    What exactly do you mean by magnification? As far as I know you can set this property for link or bookmark destinations. You can check out the [API](http://clown.sourceforge.net/docs/api/) for details (have a look at *org.pdfclown.documents.interaction.actions.GoToDestination* and *org.pdfclown.documents.interaction.navigation.document.Destination*). – beatngu13 Apr 02 '14 at 05:56
  • i want to set property of internal hyperlink to inherit zoom. – Butani Vijay Apr 02 '14 at 06:48
  • 1
    That should be possible. Again, check the [API](http://clown.sourceforge.net/docs/api/) and study *org.pdfclown.documents.interaction.annotations.Link*. – beatngu13 Apr 02 '14 at 08:05
  • Done...... Thanks, one more problem i am facing is to change page layout property to default. there is method document.setPageLayout(...) but unable to set default – Butani Vijay Apr 02 '14 at 09:03