Converting a PDF into multiple images

263 views
Skip to first unread message

Nathan Broadbent

unread,
Aug 14, 2017, 1:35:27 PM8/14/17
to Shrine
I've been struggling to do this with Carrierwave. Shrine looks much more flexible, so I've been thinking about switching to Shrine.

How would I go about converting a single PDF into multiple images, with one image per page? The Shrine docs suggest creating a new table for multiple files, but I think that would be overkill in this case. I would like to store an array of images in the metadata, or even just a page count that can be used to generate the URLs.

I've found a few hints, such as the "pdf page count" metadata on this page: http://shrinerb.com/rdoc/classes/Shrine/Plugins/AddMetadata.html
But I don't know where to go from there.

This is the code I was testing for Carrierwave:

version :jpg do
process :convert_to_images

def convert_to_images(*args)
image = MiniMagick::Image.open(current_path)
image.pages.each_with_index do |page, index|
MiniMagick::Tool::Convert.new do |convert|
convert.background 'white'
convert.flatten
convert.density 300
convert.quality 95
convert << page.path
convert << "#{CarrierWave.root}/#{store_dir}/image-#{index}.jpg"
end
end
end
end

(It doesn't work properly, but it does generate the correct images.)

I've looked at the "versions" plugin, but the documentation states that I need to return a hash of files. I really just want to return an array of generated images, and the page count.

Any help would be greatly appreciated! Also a PDF example would be really helpful in the docs.


Thanks,
Nathan


Janko Marohnić

unread,
Aug 14, 2017, 7:14:10 PM8/14/17
to Nathan Broadbent, Shrine
At the moment Shrine doesn't support arrays of uploaded files, but you can still achieve the same behaviour with a hash of versions (note that I haven't tested this):

class ImageUploader < Shrine
  plugin :versions
  plugin :processing

  process(:store) do |io, context|
    pdf      = io.download
    versions = {}

    image = MiniMagick::Image.new(pdf.path)
    image.pages.each_with_index do |page, index|
      page_image = Tempfile.new("version-#{index}", binmode: true)
      MiniMagick::Tool::Convert.new do |convert|
        convert.background 'white'
        convert.flatten
        convert.density 300
        convert.quality 95
        convert << page.path
        convert << page_image.path
      end
      page_image.open # refresh updated file
      versions[:"page_#{index + 1}"] = page_image
    end

    versions
  end
end

Assuming you have a "Document" model and you attached a PDF to a "file" attachment field, you can then retrieve an array of pages with Hash#values:

pages = document.file.values
pages #=> [...array of pages...]
pages.count #=> number of pages

I've added it to my TODO list to show this kind of example in the documentation.

Kind regards,
Janko

--
You received this message because you are subscribed to the Google Groups "Shrine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-shrine+unsubscribe@googlegroups.com.
To post to this group, send email to ruby-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ruby-shrine/cd383c83-22ba-423b-98cd-1830eb601458%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

daniba...@gmail.com

unread,
Feb 11, 2019, 7:07:24 AM2/11/19
to Shrine
Hi, i'm use this Convert PDF to Image Software this is veri nice tool windows application, need the function of PDF to image conversion. Then, use this gives me the solution. I've got idea with this suggestion. visit at:- https://www.pdfchamp.com/pdf-to-image.html
Reply all
Reply to author
Forward
0 new messages