How to crop out a part of PDF file?
Can someone help me to implement this so the page size remains the same.
This is the current code I'm using to crop the page.
PdfRectangle rect = new PdfRectangle(55, 0, 1000, 1000); PdfDictionary pageDict; for (int curentPage = 2; curentPage pdfReader.getNumberOfPages(); curentPage++) { pageDict = pdfReader.getPageN(curentPage); pageDict.put(PdfName.CROPBOX, rect); }
Posted on StackOverflow on Nov 6, 2014 by user2837742
In your code sample, you are cropping the pages. This reduces the visible size of the page.
Based on your description, you don't want cropping. Instead you want clipping.
I've written an example that clips the content of all pages of a PDF by introducing a margin of 200 user units (that's quite a margin). The example is called ClipPdf and you can see a clipped page here: hero_clipped.pdf (the iText superhero has lost arms, feet and part of his head in the clipping process.)
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2019 iText Group NV
Authors: iText Software.
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
/**
* Example written by Bruno Lowagie in answer to:
* https://stackoverflow.com/questions/26773942/itext-crop-out-a-part-of-pdf-file
*/
package com.itextpdf.samples.sandbox.stamper;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
import org.junit.experimental.categories.Category;
import java.io.File;
import java.util.Locale;
@Category(SampleTest.class)
public class ClipPdf extends GenericTest {
public static final String DEST = "./target/test/resources/sandbox/stamper/clip_pdf.pdf";
public static final String SRC = "./src/test/resources/pdfs/hero.pdf";
public static void main(String[] args) throws Exception {
File file = new File(DEST);
file.getParentFile().mkdirs();
new ClipPdf().manipulatePdf(DEST);
}
@Override
protected void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));
int n = pdfDoc.getNumberOfPages();
PdfDictionary page;
PdfArray media;
for (int p = 1; p <= n; p++) {
page = pdfDoc.getPage(p).getPdfObject();
media = page.getAsArray(PdfName.CropBox);
if (media == null) {
media = page.getAsArray(PdfName.MediaBox);
}
float llx = media.getAsNumber(0).floatValue() + 200;
float lly = media.getAsNumber(1).floatValue() + 200;
float w = media.getAsNumber(2).floatValue() - media.getAsNumber(0).floatValue() - 400;
float h = media.getAsNumber(3).floatValue() - media.getAsNumber(1).floatValue() - 400;
// !IMPORTANT to write Locale
String command = String.format(
Locale.ENGLISH,
"\nq %.2f %.2f %.2f %.2f re W n\nq\n",
llx, lly, w, h);
new PdfCanvas(pdfDoc.getPage(p).newContentStreamBefore(), new PdfResources(), pdfDoc).writeLiteral(command);
new PdfCanvas(pdfDoc.getPage(p).newContentStreamAfter(), new PdfResources(), pdfDoc).writeLiteral("\nQ\nQ\n");
}
pdfDoc.close();
}
}
Obviously, you need to study this code before using it. Once you understand this code, you'll know that this code will only work for pages that aren't rotated. If you understand the code well you should have no problem adapting the example for rotated pages.
Some pointers
The re
operator constructs a rectangle. It takes four parameters (the values preceding the operator) that define a rectangle: the x coordinate of the lower-left corner, the y coordinate of the lower-left corner, the width and the height.
The W
operator sets the clipping path. We have just drawn a rectangle; this rectangle will be used to clip the content that follows.
The n
operator starts a new path. It discards the paths we've constructed so far. In this case, it prevents that the rectangle we have drawn (and that we use as clipping path) is actually drawn.
The q
and Q
operators save and restore the graphics state stack, but that's rather obvious.
Click How to crop out a part of PDF file? if you want to see how to answer this question in iText 5.