0

I'm trying to scale a pdf file like scaling function in copier machine that can scale the document by percentage (like this : https://inspectapedia.com/graphics/Safari_Page_Setup.jpg), i'm using pdfbox to manage my pdf file. I have tried this code, but why it's not working? there's no error in the code.

void Scale(){
    try
    {
        PDDocument doc = PDDocument.load(new File(filePath));
        for (int p = 0; p < doc.getNumberOfPages(); ++p)
        {
            PDRectangle mediaBox = doc.getPage(p).getMediaBox();
            mediaBox.transform(Matrix.getScaleInstance(0.5f, 0.5f));
            doc.getPage(p).setMediaBox(mediaBox);
        }

        doc.save(new File(filePathEdited));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Is anyone know why that code is not working?

EDIT
I need it to work on API 16

Sandy Rizky
  • 163
  • 2
  • 14
  • Please clarify what you mean with "code is not working". – Tilman Hausherr Jan 23 '19 at 08:58
  • the pdf still the same, nothing change. But the code is executed when i debug it, and it create new file ( doc.save(new File(filePathEdited)); ). But this part ( mediaBox.transform(Matrix.getScaleInstance(0.5f, 0.5f)); ) is not scaling the pdf, am i doing it wrong? – Sandy Rizky Jan 23 '19 at 09:10
  • 1
    PDRectangle.transform() returns a path. It doesn't change the argument. I think what you want is this: https://stackoverflow.com/a/49689891/535646 – Tilman Hausherr Jan 23 '19 at 09:19
  • 1
    i need it to work on api 16, this code PDPageContentStream cs = new PDPageContentStream(doc, page, AppendMode.PREPEND, true) only work on api 19 and above – Sandy Rizky Jan 23 '19 at 09:33
  • 1
    Sorry I hadn't noticed that it is about PDFBox for Android. I don't know if they ever implemented the prepend feature. The best would be 1) implement it for PDFBox desktop and see if it is what you need or not; what you apparently intended (make the rectangle smaller) would just create a smaller media box but not make the contents smaller. If yes, then look into the source code how this "prepend" thing is done, and then do that with PDFBox for Android, i.e. insert the raw scaling commend into the content stream / content stream array. – Tilman Hausherr Jan 23 '19 at 09:42
  • 1
    actually i want to make the content smaller – Sandy Rizky Jan 23 '19 at 10:04
  • 1
    Yes, and to do this the best way is to prepend code in the page content stream that does a transformation, e.g. 0.9 0 0 0.9 0 0 cm \n . – Tilman Hausherr Jan 23 '19 at 10:08
  • 1
    Another possible idea: get the source for PDFBox 1.8 for desktop and search for the RemoveAllText.java example. That one shows how to get a content stream (`page.getContents`) and how to write it back (`PDStream.createOutputStream()` and `page.setContents()`). So what you should do is to write back the same content stream, but at the beginning with the string I mentioned in my previous comment. Maybe try that and create a new question as you work on this. – Tilman Hausherr Jan 23 '19 at 11:20

1 Answers1

3

First of all,

mediaBox.transform(Matrix.getScaleInstance(0.5f, 0.5f));

does not change the mediaBox to be half its former size. Instead it returns a path that represents the scaled rectangle; as you ignore the return value of that expression, this line of your code essentially is a NOP (no-operation).

If you think about it for a short while, you'll see that the transform method obviously cannot change the rectangle to the result of the transformation as that result of an arbitrary affine transformation needs not be a rectangle anymore, in particular not one parallel to the page edges.

That being said, even if your code scaled the media box, the result still wouldn't be what you want, the result pdf would show only a section of the original page as you would only scale the visible section of the canvas but not its contents.

Thus, in addition to actually scaling the media box, you also have to scale the contents. I.e. you have to pre-pend an additional content stream to the page contents and change the current transformation matrix by the scaling transformation.

mkl
  • 90,588
  • 15
  • 125
  • 265