Pdfbox : Draw image in rotated page by 270 degree [duplicate] - java

I have a simple A4 pdf document with a property /Rotate 90 : The original version of my pdf is landscape but printed portrait.
I am trying to draw a small image at the bottom left of the portait document.
Here is my code so far :
File file = new File("rotated90.pdf");
try (final PDDocument doc = PDDocument.load(file)) {
PDPage page = doc.getPage(0);
PDImageXObject image = PDImageXObject.createFromFile("image.jpg", doc);
PDPageContentStream contents = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, false, true);
contents.drawImage(image, 0, 0);
contents.close();
doc.save(new File("newpdf.pdf"));
}
Here is the end result : As you can see the image was placed at the top left (which was the 0,0 coordinate before rotation) and was not rotated.
I tried playing with drawImage(PDImageXObject image, Matrix matrix) without success.
Here is the orignal document pdf with 90° rotation

Here's a solution for a page that is rotated 90°:
PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
PDImageXObject image = ....
cs.saveGraphicsState();
cs.transform(Matrix.getRotateInstance(Math.toRadians(90), page.getCropBox().getWidth() + page.getCropBox().getLowerLeftX(), 0));
cs.drawImage(image, 0, 0);
cs.restoreGraphicsState();
cs.close();
If it is only the image, then you don't need the save/restore.
Solution for a page that is rotated 270°:
cs.transform(Matrix.getRotateInstance(Math.toRadians(270), 0, page.getCropBox().getHeight() + page.getCropBox().getLowerLeftY()));
For 180°:
cs.transform(Matrix.getRotateInstance(Math.toRadians(180), page.getCropBox().getWidth() + page.getCropBox().getLowerLeftX(), page.getCropBox().getHeight() + page.getCropBox().getLowerLeftY()));

Related

Positioning A4 image as page inside PDF file using pdfbox

I have a file jpg file: 2480 x 3508 pixels which is the suitable size for 4A.
I need to put this file in a pdf.
PDDocument doc = new PDDocument();
ByteArrayOutputStream os = new ByteArrayOutputStream();
InputStream certificate = getClass().getResourceAsStream("certificate.jpg");
BufferedImage bi = ImageIO.read(certificate);
PDPage page = new PDPage(PDRectangle.A4);//<<---- A4
doc.addPage(page);
PDImageXObject pdImageXObject = LosslessFactory.createFromImage(doc, bi);
PDPageContentStream contentStream = new PDPageContentStream(doc, page,
PDPageContentStream.AppendMode.APPEND, false);
contentStream.drawImage(pdImageXObject, 0, -10);
contentStream.close();
doc.save( "c://appfiles//PDF_image.pdf" );
doc.close();
The problem is that the generated file is totally off and not fitting the A4 size in the PDF.
The source file: https://i.stack.imgur.com/a0ZHG.jpg
The generated File: https://www.dropbox.com/s/ufo3246b6eoz3f5/PDF_image.pdf?dl=1
I know I can play with the width and height but then the printing quality drops and I think the PDRectangle.A4 was intended to prevent these kind of manipulations.
How can I make the 2480 x 3508 pixels fit to PDRectangle.A4 pdf page?
Thanks
The dimensions of PDF are on 72 dpi,
System.out.println(PDRectangle.A4); // output is [0.0,0.0,595.27563,841.8898]
your image is 300 dpi, so you have to scale:
contentStream.drawImage(pdImageXObject, 0f, -10f,
pdImageXObject.getWidth() / 300f * 72,
pdImageXObject.getHeight() / 300f * 72);
I also recommend to use JPEGFactory.createFromStream(), this is faster, smaller and uses the jpeg stream directly. Your result PDF file is 580 KB instead of 2555 KB.

Flip PDF with pdfbox

I've been trying to figure out how to flip a pdf for a while, but haven't figured out yet.
I've only found how to flip image using Graphics2D:
// Flip the image vertically
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -image.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
image = op.filter(image, null);
Could you please help me to get it with PDFbox?
Thanks!!
With PDFBox 2.*, you need to prepend it to the page content stream. Optionally save and restore graphics state, useful for further modifications. (All based on this answer)
PDPage page = doc.getPage(0);
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.PREPEND, true))
{
cs.saveGraphicsState();
cs.transform(Matrix.getScaleInstance(1, -1));
cs.transform(Matrix.getTranslateInstance(0, -page.getCropBox().getHeight()));
cs.saveGraphicsState();
}
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true))
{
cs.restoreGraphicsState();
cs.restoreGraphicsState();
}

iText - Clone existing content and add in same page

I want to know if an existing content of a PDF can be cloned using iText. Basically I have a PDF in the below format:
Without cloning the content
I want to clone the content that is on the left side in the above PDF and want the result as per the below format.
After cloning the content
I am wondering if this is possible using iText PdfStamper class or any other class of iText?
Updating the code with iText7
public void clonePageContent(String dest) throws IOException {
// Initialize PDF Document
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
PdfDocument sourcePdf = new PdfDocument(new PdfReader(SRC));
// Original page
PdfPage origPage = sourcePdf.getPage(1);
// Original page size
Rectangle orig = origPage.getPageSize();
PdfFormXObject pageCopy = origPage.copyAsFormXObject(pdf);
// N-up page
PageSize nUpPageSize = PageSize.LETTER;
PdfPage page = pdf.addNewPage(nUpPageSize);
page.setRotation(90);
PdfCanvas canvas = new PdfCanvas(page);
// Scale page
AffineTransform transformationMatrix = AffineTransform
.getScaleInstance(
nUpPageSize.getWidth() / orig.getWidth() / 2f,
nUpPageSize.getHeight() / orig.getHeight() / 2f);
canvas.concatMatrix(transformationMatrix);
// Add pages to N-up page
canvas.addXObject(pageCopy, 0, orig.getHeight());
canvas.addXObject(pageCopy, orig.getWidth(), orig.getHeight());
pdf.close();
sourcePdf.close();
}
With the above code, I am not able to produce the output as expected. Can someone throw some light as to what should be tweaked to get the above expected output?
After so many days of struggle, the below code helps in achieving the above output that I was expecting. Hope this might be helpful to someone, someday!
P.S: I am newbie to iText7.
public void clonePageContent(String dest) throws IOException {
// Initialize PDF Document
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
PdfDocument sourcePdf = new PdfDocument(new PdfReader(SRC));
// Original page
PdfPage origPage = sourcePdf.getPage(1);
// Original page size
Rectangle orig = origPage.getPageSize();
PdfFormXObject pageCopy = origPage.copyAsFormXObject(pdf);
//PdfCanvas canvas = new PdfCanvas(pageCopy,sourcePdf);
// N-up page
PageSize nUpPageSize = PageSize.LETTER;
PdfPage page = pdf.addNewPage(nUpPageSize).setRotation(90);
PdfCanvas canvas = new PdfCanvas(page);
// Scale page
AffineTransform transformationMatrix = AffineTransform
.getScaleInstance(
page.getPageSize().getWidth() / orig.getWidth(), page.getPageSize().getHeight() / orig.getHeight()
);
canvas.concatMatrix(transformationMatrix);
System.out.println(page.getPageSize().getWidth());
System.out.println(orig.getWidth());
// Add pages to N-up page
canvas.addXObject(pageCopy, 0, 0);
canvas.addXObject(pageCopy, 0, 350f); //350f
//canvas.addXObject(pageCopy, orig.getRight(), orig.getWidth());
pdf.close();
sourcePdf.close();
}

Cannot capture annotations in a PDImageXObject using PDFBox

I am highlighting (in green) certain words on each page of my input pdf document using PDAnnotationTextMarkup. A sample screenshot is seen below;
However, when I crop this part of the page and try to save it as a PDImageXObject, I get the following result;
The code I am using to crop the image is as follows;
public PDImageXObject cropAndSaveImage(int pageNumber, Rectangle dimensions)
{
PDImageXObject pdImage = null;
// Extract arguments from the rectangle object
float x = dimensions.getXValue();
float y = dimensions.getYValue();
float w = dimensions.getWidth();
float h = dimensions.getHeight();
PDRectangle pdRectangle;
int pageResolution = 140;
try{
// Fetch the source page
PDPage sourcePage = document.getPage(pageNumber-1);
// Calculate height of the source page
PDRectangle mediaBox = sourcePage.getMediaBox();
float sourcePageHeight = mediaBox.getHeight();
// Fetch the original crop box of the page
PDRectangle originalCrop = sourcePage.getCropBox();
/*
* PDF Crop Box - Here we initialize the rectangle area
* that is needed to crop a region from the PDF document
*/
if(pageOriginShifted)
{
pdRectangle = new PDRectangle(x, sourcePageHeight - y, w, h);
}
else
{
pdRectangle = new PDRectangle(x, y, w, h);
}
// Crop the required rectangle from the source page
sourcePage.setCropBox(pdRectangle);
// PDF renderer
PDFRenderer renderer = new PDFRenderer(document);
// Convert to an image
BufferedImage bufferedImage = renderer.renderImageWithDPI(pageNumber-1, pageResolution, ImageType.RGB);
pdImage = LosslessFactory.createFromImage(document, bufferedImage);
// Restore the original page back to the document
sourcePage.setCropBox(originalCrop);
return pdImage;
}catch(Exception e)
{
Logger.logWithoutTimeStamp(LOG_TAG + "cropAndSaveImage()", Logger.ERROR, e);
}
return null;
}
I am quite perplexed on why the highlighted text in green won't show up. Any help in this regard is highly appreciated (I cannot attach the input PDF document owing to privacy issues).
Thanks in advance,
Bharat.

Insert image as new layer to existing PDF using PdfBox 1.8.8

I'm using PDFBox in my application to modify existing PDF files.
I need to place a barcode to the first page of the PDF document.
So first i create new PDF file with inserted barcode:
PDDocument document = new PDDocument();
PDXObjectImage ximage = new PDPixelMap(document, awtImage);
PDPage pag = new PDPage(new PDRectangle(ximage.getWidth(), ximage.getHeight()));
document.addPage(pag);
PDPageContentStream stream = new PDPageContentStream(document, pag, false, false);
stream.drawXObject(ximage, 0, 0, ximage.getWidth(), ximage.getHeight());
stream.close();
Then i try to place it as new layer into existing PDF:
Point barlocation = new Point(0,0);
float Height = page.getMediaBox().getHeight();
float Width = page.getMediaBox().getWidth();
barlocation.setLocation(Width - pag.getMediaBox().getWidth(), Height - pag.getMediaBox().getHeight()); //I need to place it in the top right corner
LayerUtility layerUtility = new LayerUtility(doc);
List bigPages = doc.getDocumentCatalog().getAllPages();
PDXObjectForm firstForm = layerUtility.importPageAsForm(document, 0);
AffineTransform affineTransform = new AffineTransform();
affineTransform.translate(barlocation.x , barlocation.y);
layerUtility.appendFormAsLayer((PDPage) bigPages.get(0), firstForm, affineTransform, "barcode layer");
doc.save(path);
doc.close();
So it works well with PDF document ver 1.5 (created in MS Word 2010/2013). But it's not working correctly with PDF document version 1.6 position and size of the inserted layer are wrong (i can't post an image, so you can see the result here:http://img4.imagetitan.com/img.php?image=11_capture567.png
What should I change? Thanks for reading and sorry for my bad English.

Categories

Resources