julianhille / MuhammaraJS

Muhammara a node module with c/cpp bindings to modify PDF with js for node or electron (based/replacement on/of galkhana/hummusjs)
Other
229 stars 46 forks source link

How to split 10% of pdf and add watermark with muhammara js #284

Closed natnaeltibebu closed 1 year ago

natnaeltibebu commented 1 year ago

I have several pdfs. How can I split 10% of each of them? Add a watermark and send to the browser.please help me.

julianhille commented 1 year ago

What do you mean by split by 10%?

100 pages and only want to give first 10 or cut each page at head or bottom or left or right at 10 percent?

I'm not sure what are you trying to achieve.

natnaeltibebu commented 1 year ago

Yes, if there are 100 pages, I want to split the first 10 pages

natnaeltibebu commented 1 year ago

Hey, can you please give me an idea.

julianhille commented 1 year ago

Here is how to serve dynamically created pdf with express: https://github.com/julianhille/MuhammaraJS/blob/develop/docs/How-to-serve-dynamically-created-pdf.md

You need to open the input file, get the amount of pages and create a writer.

To copy files from one to another have a look at: mergePDFPagesToPage

let readerPath = 'pathToFile.pdf'
let writer = muhammara.createWriter(destination)
let reader = muhammara.createReader(readerPath)
let pageCount = Math.max(Math.ceil(reader.getPagesCount() / 10), 1)
let pageDimension = {}
const xobjectForm = writer.createFormXObjectsFromPDF(readerPath, muhammara.ePDFPageBoxMediaBox)
for (let i = 1; i < pageCount; i++) {
      pageDimensions = {
        height: reader.parsePage(i).getMediaBox()[3],
        width: reader.parsePage(i).getMediaBox()[2]
      }
      const page = writer.createPage(0, 0, pageDimensions.width, pageDimensions.height)
      const pageContent = writer.startPageContentContext(page)
      let graphicObject = pageContent.q()
      graphicObject
        .cm(1, 0, 0, 1, 0, 0)
        .doXObject(page.getResourcesDictionary().addFormXObjectMapping(xobjectForm[i]))
        .Q()
       writer.writePage(page)
}
writer.end()

this would copy page by page and you could alter the pages with your watermark which might be text or tiff or png or whatever else.

** EDIT: corrected snippet

natnaeltibebu commented 1 year ago

I got the following error: basePDF is not defined.

julianhille commented 1 year ago

sorry missed something createFormXObjectsFromPDF reads from a path so it should be the same as the reader, to be consistent

natnaeltibebu commented 1 year ago

Thank you, but now it generates corrupted PDFs. I tried with different PDFs, but the output is not working.

julianhille commented 1 year ago

Please send a minimal version and an example file. You may attach it as zip here

natnaeltibebu commented 1 year ago
let muhammara = require('muhammara')

let readerPath = './test.pdf'
let writer = muhammara.createWriter('./output.pdf')
let reader = muhammara.createReader(readerPath)
let pageCount = Math.max(Math.ceil(reader.getPagesCount() / 10), 1)
let pageDimension = {}
const xobjectForm = writer.createFormXObjectsFromPDF(readerPath, muhammara.ePDFPageBoxMediaBox)
for (let i = 1; i < pageCount; i++) {
    pageDimensions = {
        height: reader.parsePage(i).getMediaBox()[3],
        width: reader.parsePage(i).getMediaBox()[2]
    }
    const page = writer.createPage(0, 0, pageDimensions.width, pageDimensions.height)
    const pageContent = writer.startPageContentContext(page)
    let graphicObject = pageContent.q()
    graphicObject
        .cm(1, 0, 0, 1, 0, 0)
        .doXObject(page.getResourcesDictionary().addFormXObjectMapping(xobjectForm[i]))
        .Q()

}

this is what i tried based on the above example

julianhille commented 1 year ago

you need to end the writer, updated the content above. You also need to write the page to the writer.

natnaeltibebu commented 1 year ago

Thank you so much! It's working now. Just one last question: what is the page when I pass the page number and an invalid parameter error pops out, and where should I put the watermark text?

julianhille commented 1 year ago

what is the page when I pass the page number and an invalid parameter error pops out

i'm unsure what page or parameter you are referring to.

The watermark should be put after copying the page, otherwise you might overwrite the watermark with the objects from the original page.

natnaeltibebu commented 1 year ago

Thank you so much for this great library!

julianhille commented 1 year ago

you're welcome. you can always buy me a coffee :P

blankstar85 commented 1 year ago

@julianhille I'm new to this, but reading a lot, but can't figure this out. Is there a way to do the above from a readable stream? I get hung up on the Xobject.

Could this be created from the pdf reader? I have the file as a base64 string and not a file.

const pdfWriter = createWriter('./pdfChunk.pdf'); const pdfReader = createReader(new PDFRStreamForBuffer(Buffer.from(pdfAt.contentBytes, 'base64')), { password: '7G"(9YErEg', }); for (let i = 1; i < 4; i++) { const pageDimension = { height: pdfReader.parsePage(i).getMediaBox()[3], width: pdfReader.parsePage(i).getMediaBox()[2], }; const page = pdfWriter.createPage(0, 0, pageDimension.width, pageDimension.height); const pageContent = pdfWriter.startPageContentContext(page); const graphicObject = pageContent.q(); graphicObject.cm(1, 0, 0, 1, 0, 0).doXObject().Q(); pdfWriter.writePage(page); } pdfWriter.end();

julianhille commented 1 year ago

would you mind opening a new ticket and maybe create reference to this one please.

blankstar85 commented 1 year ago

would you mind opening a new ticket and maybe create reference to this one please.

I did thanks!