Как сделать миниатюру многостраничного PDF с помощью скрепки - PullRequest
6 голосов
/ 16 августа 2010

Мне бы хотелось, чтобы Paperclip создавал 2 эскиза для каждой загруженной страницы многостраничного файла PDF.

Я использую Paperclip 2.3.1.1 и использую это в моей модели активов:

    has_attached_file :asset,
                  :styles => { :medium => "800x600>", :thumb => "100x100>" }

Итак, когда я загружал 3-страничный файл PDF, я надеялся, что это создаст 2 превью на страницу (по одному на 800x600 и меньшее изображение на 100x100). Вместо этого я создаю 3 папки (thumb, medium, original) - исходная папка содержит pdf-файл origianl, в то время как thumb и medium содержат pdf, в котором пикселирована только первая страница pdf.

Что мне нужно сделать, чтобы скрепка создала 2 превью для каждой страницы PDF? В идеале, я хотел бы, чтобы на этой странице было одно изображение (создано 6 изображений):


активы / 1 / средний / файл-0.png

активы / 1 / средний / файл-1.png

активы / 1 / средний / файл-2.png

активы / 1 / палец / файл-0.png

активы / 1 / палец / файл-1.png

активы / 1 / палец / файл-2.png

Кто-нибудь знает, как это сделать? Нужен ли пользовательский процессор? Если да, то как бы выглядел процессор?

Спасибо.

Ответы [ 2 ]

9 голосов
/ 20 июля 2011

Вот как я реализовал подобную задачу.

Модель документа:

class Document < ActiveRecord::Base

  has_many :pages, :dependent => :destroy

  has_attached_file :asset

  after_asset_post_process :make_pages

  private

  def make_pages
    if valid?
      Paperclip.run('convert', "-quality #{Page::QUALITY} -density #{Page::DENSITY} #{asset.queued_for_write[:original].path} #{asset.queued_for_write[:original].path}%d.png")
      images = Dir.glob("#{asset.queued_for_write[:original].path}*.png").sort_by do |line|
        line.match(/(\d+)\.png$/)[1].to_i
      end

      images.each do |page_image|
        pages.build(:asset => File.open(page_image))
      end
      FileUtils.rm images
    end
  end
end

Модель страницы:

class Page < ActiveRecord::Base

  belongs_to :document

  has_attached_file :asset

  QUALITY = 100
  DENSITY = '80x80'

end
3 голосов
/ 16 октября 2010

У меня есть полу-рабочее решение для этого ... но оно не очень элегантно.Мне бы очень хотелось придумать что-нибудь получше, но я все равно поделился.

Я начал с определения множества новых стилей, по одному для каждой страницы ... до скольких страниц яхочу быть в состоянии справиться.(глупо, я знаю, но я не знаю, как получить доступ к интерполяции путей в Paperclip, чтобы каждая страница сохранялась / удалялась в магазине должным образом, если для каждого изображения не существует уникального стиля)* Тогда ... У меня есть собственный процессор, который подклассов от процессора Thumbnail, с некоторой дополнительной логикой для запуска команды convert с соответствующей страницей #.

module Paperclip
  # Handles thumbnailing images that are uploaded.
  class MultipageThumbnail < Thumbnail

    # Creates a Thumbnail object set to work on the +file+ given. It
    # will attempt to transform the image into one defined by +target_geometry+
    # which is a "WxH"-style string. +format+ will be inferred from the +file+
    # unless specified. Thumbnail creation will raise no errors unless
    # +whiny+ is true (which it is, by default. If +convert_options+ is
    # set, the options will be appended to the convert command upon image conversion
    def initialize file, options = {}, attachment = nil
      @page = options[:geometry].match(/\[(\d+)\]/)[1] rescue 0
      @page ||= 0
      options[:geometry] = options[:geometry].sub(/\[\d+\]/, '')
      super
    end

    # Performs the conversion of the +file+ into a thumbnail. Returns the Tempfile
    # that contains the new image.
    def make
      return nil if @page >= page_count

      src = @file
      dst = Tempfile.new([@basename, @format].compact.join("."))
      dst.binmode

      begin
        options = [
          source_file_options,
          "#{ File.expand_path(src.path) }[#{@page}]",
          transformation_command,
          convert_options,
          "#{ File.expand_path(dst.path) }"
        ].flatten.compact

        success = Paperclip.run("convert", *options)
      rescue PaperclipCommandLineError => e
        raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if @whiny
      end

      dst
    end

    def page_count
      @page_count ||= begin
        files = Paperclip.run("identify", "#{@file.path}")
        files.split(/\n/).size
      rescue PaperclipCommandLineError
        1
      end
    end

  end
end
...