【问题标题】:How to thumbnail a multi-page pdf with paperclip如何使用回形针对多页 pdf 进行缩略图
【发布时间】:2011-03-30 14:26:36
【问题描述】:

我想让 Paperclip 为上传的多页 PDF 文件的每一页创建 2 个缩略图。

我正在运行 Paperclip 2.3.1.1 并在我的资产模型中使用它:

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

所以,当我上传一个 3 页的 pdf 文件时,我希望这会在每页创建 2 个拇指(一个 800x600 和一个 100x100 的较小图像)。相反,我创建了 3 个文件夹(thumb、medium、original) - 原始文件夹包含原始 pdf 文件,而 thumb 和 medium 分别包含一个 pdf,其中只有 pdf 的第一页全部像素化。

我需要做什么才能让回形针为 pdf 的每一页创建 2 个拇指?理想情况下,我希望像这样每页一张图片(创建 6 张图片):


assets/1/medium/file-0.png

assets/1/medium/file-1.png

assets/1/medium/file-2.png

assets/1/thumb/file-0.png

assets/1/thumb/file-1.png

assets/1/thumb/file-2.png

有人知道怎么做吗?我需要定制处理器吗?如果是这样,处理器会是什么样子?

谢谢。

【问题讨论】:

    标签: ruby-on-rails pdf paperclip


    【解决方案1】:

    这里我是如何实现类似任务的。

    文档模型:

    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
    

    【讨论】:

    • 我正在尝试这个解决方案,但转换命令似乎只为第一页生成一个图像。否则效果很好。有什么想法吗?
    • 您可以在终端中使用 Imagemagick 包中的convert 命令进行调试。
    • 谢谢,我一直在玩这个。仍然没有让它工作,只为第一页生成一张图片。
    • 考虑分享您的文档并在此处咨询 Imagemagick 专家。
    • 非常好。我只是建议在构建页面之前添加类似pages.destroy_all 的内容,以防文档资产发生更改(这样您就没有旧图像了)。
    【解决方案2】:

    我对此有一个半有效的解决方案......但它不是很优雅。我真的很想想出更好的东西,但我想我还是要分享。

    我首先定义了一堆新样式,每个页面一个样式... 最多我希望能够处理多少个页面。 (愚蠢,我知道,但我不知道如何访问 Paperclip 中的路径插值,以便在商店中正确保存/删除每个页面,除非每个图像都有独特的样式)

    { ...
    :page_0 =>    {:geometry=>'800[0]',   :format=>:png, :processors=>[:multipage_thumbnail]},
    :page_1 =>    {:geometry=>'800[1]',   :format=>:png, :processors=>[:multipage_thumbnail]},
    :page_2 =>    {:geometry=>'800[2]',   :format=>:png, :processors=>[:multipage_thumbnail]},
    :page_3 =>    {:geometry=>'800[3]',   :format=>:png, :processors=>[:multipage_thumbnail]},
    :page_4 =>    {:geometry=>'800[4]',   :format=>:png, :processors=>[:multipage_thumbnail]},
    :page_5 =>    {:geometry=>'800[5]',   :format=>:png, :processors=>[:multipage_thumbnail]},
    }
    

    然后...我有一个自定义处理器,它是缩略图处理器的子类,带有一些额外的逻辑,用于使用正确的页面 # 运行转换命令。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      相关资源
      最近更新 更多