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.
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 :
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".
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);
}
}
}