我想让Paperclip为上传的多页PDF文件的每一页创建2个缩略图。
我正在运行Paperclip 2.3.1.1并在我的资产模型中使用它:
has_attached_file :asset,
:styles => { :medium => "800x600>", :thumb => "100x100>" }
所以,当我上传一个3页的pdf文件时,我希望这会每页创建2个大拇指(一个在800x600,一个小图像在100x100)。相反,我创建了3个文件夹(拇指,中等,原始) - 原始文件夹包含origianl pdf文件,而拇指和媒体各包含一个pdf,只有pdf的第一页所有像素化。
我需要做些什么才能让回形针为pdf的每一页创建2个拇指?理想情况下,我想像这样每页一个图像(创建6个图像):
资产/ 1 /中/文件0.png
资产/ 1 /中/文件1.png
资产/ 1 /中/文件2.png
资产/ 1 /拇指/文件0.png
资产/ 1 /拇指/文件1.png
资产/ 1 /拇指/文件2.png
有谁知道怎么做?我需要定制处理器吗?如果是这样,那么处理器会是什么样子?
感谢。
答案 0 :(得分:9)
这是我如何实施类似的任务。
文件模型:
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
答案 1 :(得分:3)
我有一个半工作的解决方案...但它不是很优雅。我真的想提出一些更好的东西,但无论如何我认为我会分享。
我首先定义了一堆新的样式,每个页面都有一个...我希望能够处理多少页面。 (愚蠢,我知道,但我不知道如何访问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]},
}
然后......我有一个自定义处理器,它是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