I am trying to write a pdf conversion, that will take a pdf containing 1-up portrait pages, and create a new document, but merge every 2 pages into one 2-up landscape page
ie.
the following code will scale down the content 50%, but I cant figure out how to make the new page landscape, while injecting the other page as portrait, and injecting into the top left, and right of centre
public static void main(String[] args) throws IOException, DocumentException, COSVisitorException {
scalePages("c:/pdf/in.pdf", "c:/pdf/out" + new Date().getTime() + ".pdf", 0.50f);
}
public static void scalePages(String inFile, String outFile, float scale ) throws IOException, COSVisitorException {
PDDocument doc1 = null;
try {
doc1 = PDDocument.load( inFile );
List allPages = doc1.getDocumentCatalog().getAllPages();
for( int i=0; i<allPages.size(); i++ ) {
PDPage page1 = (PDPage)allPages.get(i );
PDRectangle mediaBox = page1.getMediaBox();
float oldX = mediaBox.getUpperRightX();
float newX = oldX * scale;
float oldY = mediaBox.getUpperRightY();
float newY = oldY * scale;
mediaBox.setUpperRightX(newX);
mediaBox.setUpperRightY(newY);
PDFStreamParser parser = new PDFStreamParser(page1.getContents());
parser.parse();
List tokens = parser.getTokens();
tokens.add(0,new COSFloat(scale));
tokens.add(1,new COSInteger(0));
tokens.add(2,new COSInteger(0));
tokens.add(3,new COSFloat(scale));
tokens.add(4,new COSInteger(0));
tokens.add(5,new COSInteger(0));
tokens.add(6,PDFOperator.getOperator("cm"));
PDStream newContents = new PDStream( doc1 );
ContentStreamWriter writer = new ContentStreamWriter( newContents.createOutputStream() );
writer.writeTokens( tokens );
newContents.addCompression();
page1.setContents(newContents);
//page1.setRotation(90);
mediaBox.setUpperRightX(oldX);
mediaBox.setUpperRightY(oldY);
}
doc1.save( outFile );
} finally {
if( doc1 != null ) {
doc1.close();
}
}
}
so the result is as follows
any pointers would be greatly appreciated
Here is an example that "stitches" two one page PDFs side-by-side and saves result in a new file using PDFBox. Enjoy!
function void generateSideBySidePDF() {
File pdf1File = new File(FILE1_PATH);
File pdf2File = new File(FILE2_PATH);
File outPdfFile = new File(OUTFILE_PATH);
PDDocument pdf1 = null;
PDDocument pdf2 = null;
PDDocument outPdf = null;
try {
pdf1 = PDDocument.load(pdf1File);
pdf2 = PDDocument.load(pdf2File);
outPdf = new PDDocument();
// Create output PDF frame
PDRectangle pdf1Frame = pdf1.getPage(0).getCropBox();
PDRectangle pdf2Frame = pdf2.getPage(0).getCropBox();
PDRectangle outPdfFrame = new PDRectangle(pdf1Frame.getWidth()+pdf2Frame.getWidth(), Math.max(pdf1Frame.getHeight(), pdf2Frame.getHeight()));
// Create output page with calculated frame and add it to the document
COSDictionary dict = new COSDictionary();
dict.setItem(COSName.TYPE, COSName.PAGE);
dict.setItem(COSName.MEDIA_BOX, outPdfFrame);
dict.setItem(COSName.CROP_BOX, outPdfFrame);
dict.setItem(COSName.ART_BOX, outPdfFrame);
PDPage outPdfPage = new PDPage(dict);
outPdf.addPage(outPdfPage);
// Source PDF pages has to be imported as form XObjects to be able to insert them at a specific point in the output page
LayerUtility layerUtility = new LayerUtility(outPdf);
PDFormXObject formPdf1 = layerUtility.importPageAsForm(pdf1, 0);
PDFormXObject formPdf2 = layerUtility.importPageAsForm(pdf2, 0);
// Add form objects to output page
AffineTransform afLeft = new AffineTransform();
layerUtility.appendFormAsLayer(outPdfPage, formPdf1, afLeft, "left");
AffineTransform afRight = AffineTransform.getTranslateInstance(pdf1Frame.getWidth(), 0.0);
layerUtility.appendFormAsLayer(outPdfPage, formPdf2, afRight, "right");
outPdf.save(outPdfFile);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (pdf1 != null) pdf1.close();
if (pdf2 != null) pdf2.close();
if (outPdf != null) outPdf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I ended up doing this with itext
private String createTwoUp(String originalPdfFile) throws IOException, DocumentException {
String newFilename = FilenameUtils.getBaseName(originalPdfFile) + "_2up." + FilenameUtils.getExtension(originalPdfFile);
newFilename = FilenameUtils.concat(getPdfFileFolder(), newFilename);
PdfReader reader = new PdfReader(originalPdfFile);
Document doc = new Document(new RectangleReadOnly(842f, 595f), 0, 0, 0, 0);
PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(newFilename));
doc.open();
int totalPages = reader.getNumberOfPages();
for (int i = 1; i <= totalPages; i = i + 2) {
doc.newPage();
PdfContentByte cb = writer.getDirectContent();
PdfImportedPage page = writer.getImportedPage(reader, i); // page #1
float documentWidth = doc.getPageSize().getWidth() / 2;
float documentHeight = doc.getPageSize().getHeight();
if (i > 1) {
documentHeight = documentHeight - 65f;
}
float pageWidth = page.getWidth();
float pageHeight = page.getHeight();
float widthScale = documentWidth / pageWidth;
float heightScale = documentHeight / pageHeight;
float scale = Math.min(widthScale, heightScale);
//float offsetX = 50f;
float offsetX = (documentWidth - (pageWidth * scale)) / 2;
float offsetY = 0f;
cb.addTemplate(page, scale, 0, 0, scale, offsetX, offsetY);
if (i+1 <= totalPages) {
PdfImportedPage page2 = writer.getImportedPage(reader, i+1); // page #2
pageWidth = page.getWidth();
pageHeight = page.getHeight();
widthScale = documentWidth / pageWidth;
heightScale = documentHeight / pageHeight;
scale = Math.min(widthScale, heightScale);
offsetX = ((documentWidth - (pageWidth * scale)) / 2) + documentWidth;
cb.addTemplate(page2, scale, 0, 0, scale, offsetX, offsetY);
}
}
doc.close();
return newFilename;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With