waldrumpus
waldrumpus

Reputation: 2590

Make PDF page sizes fit image sizes

I'm trying to create a PDF document from images of varying sizes so that each page of the PDF displays one of the images unscaled, the page size should fit the image dimensions.

I'm using Prawn to generate the PDF from a list of image file names. To get the image dimensions I use FastImage.

Prawn::Document.generate('Output.pdf') do
  list_of_image_filenames.each do |i|
    image_size = FastImage.size(i)
    start_new_page(:size => image_size, :layout => :portrait)
    image(i)
  end
end

To test it I'm using three PNG files of dimensions 560x560, 600x600, and 600x600. I've made sure that FastImage returns the correct image dimensions.

The resulting PDF (Preview tells me it's PDF version 1.4) looks like this:

  1. It starts with 3 empty pages (one of which is probably due to the fact that I didn't put anything on the first page), then the first image, which is cropped. Except the first one, which I'm ignoring for now, these pages are of size 560x560 px, according to Preview.
  2. Next are two empty pages, then the second image, which also doesn't fit on the page. These pages have dimensions 600x600 px.
  3. Finally, two more blank pages and the third image, cropped again, page dimensions also 600x600 px.

Here is a sample of one of the cropped images; the original image is a complete rounded rectangle with the digit "1" inside.

Sample of incorrectly displayed image

Why do the images not fit on the page? How can I put the individual unscaled images on pages fitting their dimensions?

Upvotes: 1

Views: 2216

Answers (2)

WINGLEUNG CHOI
WINGLEUNG CHOI

Reputation: 134

https://github.com/boazsegev/combine_pdf

you could try this gem.

cropped_size = [X0, Y0, X_max, Y_max]
combine_pdf = CombinePDF.new(pdf_path)
combine_pdf.pages.each{|page| page.crop(cropped_size)}
combine_pdf.save(new_pdf_path)

Upvotes: 1

engineersmnky
engineersmnky

Reputation: 29328

May not be an exact answer but Probably too long for a comment. I have a few suggestions: Have you tried specifying image size and position? e.g.

image(i,position: :left, vposition: :top, fit: image_size)

This will place an image in the top left corner of the document an will force it to fit in dimensions of the image_size Array. This might help with the cropping.

Also when setting page_size you need to pad for margins otherwise the image will not fit because it is outside the writable area try something like

image_size = FastImage.size(i)
#default margins are 0.5 inches so pad both height and width with 1 inch using in2pt
page_size = image_size.map{|p| p + in2pt(1) }
start_new_page(:size => page_size, :layout => :portrait)

I cannot guarantee this will work and it has not been tested but usually overflow onto additional pages has to do with the fact that you cannot place a specific object inside the bounds so padding the page size should help.

Upvotes: 3

Related Questions