galkahana / HummusJS

Node.js module for high performance creation, modification and parsing of PDF files and streams
http://www.pdfhummus.com
Other
1.14k stars 169 forks source link

drawImage with pdf to include markup/comment also #327

Open vegarringdal opened 5 years ago

vegarringdal commented 5 years ago

Hi

I need to scale pages to A3 && A4 sizes if they are smaller or bigger then this size. Currently simple code is scaling the pages very nicely(pdf still searchable text), but markups/comment/stamps added in acrobat is not included. Is there something very simple I can do to get drawimage to include this too ?

image

const hummus = require('hummus');
const path = require('path');
const file_path = path.resolve(__dirname, './original.pdf')
const resizeWriter = hummus.createWriter(path.resolve(__dirname, './test.pdf'))
const resizeReader = hummus.createReader(file_path)
const resize_page_count = resizeReader.getPagesCount()

// A4 size
const maxWidth = 210;
const maxHeight = 297;

for (let i = 0; i < resize_page_count; i++) {

  // get media box so I can get width and height
  const onepage = resizeReader.parsePage(i);
  const getMediaBox = onepage.getMediaBox();

  //get new width and height based landscape/portrait
  let width = getMediaBox[2] > getMediaBox[3] ? maxHeight : maxWidth;
  let height = getMediaBox[2] > getMediaBox[3] ? maxWidth : maxHeight;

  const page = resizeWriter.createPage(0, 0, width, height)
  const pageContent = resizeWriter.startPageContentContext(page)

  pageContent
    .q()
    .drawImage(0, 0, file_path, {
      index: i,
      transformation: {
        width: width,
        height: height,
        proportional: true
      }
    })
    .Q()

  resizeWriter.writePage(page)
}

resizeWriter.end() 
vegarringdal commented 5 years ago

I tried to just copy "Annots" from 1 pdf to another But looks like Im mastering failure when it comes to Annots Even if I get this part under to work I guess it will be placed wrong if I combine with with the drawimage above. size Ill be making some pages smaller and some bigger. Is it possible to get the drawImage to support annots(everythign in source pdf)?


const hummus = require('hummus');
const path = require('path');

// paths of my pdf
const inputPDF = path.resolve(__dirname, './input.pdf')
const outputPDF = path.resolve(__dirname, './output.pdf')

// reader & writer
const inputPDF_reader = hummus.createReader(inputPDF)
const outputPDF_writer = hummus.createWriter(outputPDF)

// create a page in the size I want it
const page = outputPDF_writer.createPage(0, 0, 210, 297) //atm same size, but it wont be
const pageContent = outputPDF_writer.startPageContentContext(page)

// add the page and get the page ID so we can add our annots to it
const newPageID = outputPDF_writer.writePageAndReturnID(page)

// get copying context and page1 from where we want to copy content
const copyingContext = outputPDF_writer.createPDFCopyingContext(inputPDF);
const sourcePage1Objects = copyingContext.getSourceDocumentParser().parsePage(0).getDictionary().toJSObject();

// get objects context
const objectsContext = outputPDF_writer.getObjectsContext();

// start modifying indirect objects for page 1 ? (think Im doing something wrong here)
objectsContext.startNewIndirectObject(newPageID);

// start dictionary
const modifiedPageObject = objectsContext.startDictionary();
Object.getOwnPropertyNames(sourcePage1Objects).forEach(function(element, index, array) {
    // just see if I manage to copy annotations (think this is the markup/comments/stamps etc)
    if (element === 'Annots') {
        // how can I check if this even have content?
        // Im I copying anything at all ?
        modifiedPageObject.writeKey(element);
        copyingContext.copyDirectObjectAsIs(sourcePage1Objects[element]);
    }
});

//end dictionary && indirectObject
objectsContext.endDictionary(modifiedPageObject).endIndirectObject();

outputPDF_writer.end();

sample pdf input.pdf

vegarringdal commented 5 years ago

Note to my self: Check out these: https://github.com/galkahana/HummusJSSamples/tree/master/appending-pages-with-comments https://github.com/galkahana/hummus-annotation-example

@galkahana I haveto say Im impressed how much this lib is able to to do. Thank for making it 👍 Ofc there are a lot of parts I dont understand, but again there is a lot I dont know about PDF format 😂

Do you have any tips on how resizing with annotations, anything I should think about ? IS there something I just wont be able to do ? And is its possible to ask for feature request on the drawImage to include markups, looks like a very nice way to do it, resize first, then add own comments etc if needed after. Hope you get time to answer :-)

galkahana commented 5 years ago

Thank you. You can resize the annotations, yes. annotations have rect, so when copying annotations you can copy all but rect, and then write the rect that you want. the pdf specs can tell you more feature of annotations if you want them.

All default copying methods of hummus (either page appending, or drawing image or whatnot) copy just the graphics. it leaves any annotations or global document features (like forms) alone, because its generally trickier to determine what would be generally good to do (forms give most headaches as some elements tie to the document instead of the page). so i left it with copying the graphics and leaving the rest to the decision of the user.

i wouldn't mind if anyone would share an example or write a module or whatnot, showing how to copy and image with markups that make sense.

Gal.