【问题标题】:How to convert a PDF into an array of images, with Carrierwave and MiniMagick (Ruby on Rails)如何使用 Carrierwave 和 MiniMagick (Ruby on Rails) 将 PDF 转换为图像数组
【发布时间】:2017-08-14 16:46:29
【问题描述】:

我正在将上传的 PDF 转换为图片,每页一张图片。我已经知道如何使用MiniMagick::Tool::Convert 生成图像,但我不知道如何为 Uploader 编写 version 块,以便我可以访问图像 URL 数组。

这是我目前的上传者:

class DocumentUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  storage :file
  # storage :fog

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :jpg do
    process :convert_to_images
    process :set_content_type_jpg

    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

  def set_content_type_jpg(*args)
    self.file.instance_variable_set(:@content_type, "image/jpg")
  end

  # Add a white list of extensions which are allowed to be uploaded.
  def extension_white_list
    %w(jpg jpeg gif png doc docx pdf)
  end
end

这会在正确的目录中生成image-0.jpgimage-1.jpg 等。但现在我无法在我的视图中引用这些图像,甚至不知道有多少。当我需要将图像上传到 S3 时,这也不起作用。如何让 Carrierwave 处理此图像集合而不是单个图像的文件存储?

看起来我可能需要添加一个新的数据库列来存储页数。有没有办法让我的上传者根据这个计数返回一组图片 URL?

我也愿意切换到另一个 gem。使用 Paperclip、Shrine 或 Refile 会更容易吗?

【问题讨论】:

  • 嗨,我知道这有点晚了,但这个要点解释了如何在数据库中为图像创建记录。 gist.github.com/bbasseri/2517376 我刚刚开始将它应用到您的代码中,它似乎可以工作。感谢您的帖子,我花了几个小时试图找到一种将 PDF 转换为图像的好方法。

标签: ruby-on-rails image imagemagick carrierwave minimagick


【解决方案1】:

使用 Shrine,您可以为每个页面制作不同的版本:

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

假设您有一个 Document 模型,并且您将 PDF 附加到 file 附件字段,然后您可以使用 Hash#values 检索页面数组:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2020-03-26
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    相关资源
    最近更新 更多