我正在以这种方式处理 PDF 文件的缩略图:
version :thumb do
process :resize_to_limit => [260, 192]
process :convert => :jpg
process :set_content_type
end
def set_content_type(*args)
self.file.instance_variable_set(:@content_type, "image/jpeg")
end
但是当 PDF 文件是多页时,它会为一个 jpg 文件中的所有页面生成缩略图。 有没有办法只为第一页生成缩略图?
我今年早些时候提交了一个补丁就是为了做到这一点。使用自定义处理器:
def cover
manipulate! do |frame, index|
frame if index.zero?
end
end
process :cover
Tanzeeb 的出色解决方案!谢谢你。
所以我可以做这样的事情:
def cover
manipulate! do |frame, index|
frame if index.zero?
end
end
并将其用于拇指生成
version :thumb do
process :cover
process :resize_to_fill => [50, 50, Magick::NorthGravity]
process :convert => 'png'
end
太棒了!
我在寻找同一问题的解决方案时遇到了这篇文章。当您将 pdf 转换为 jpeg 时,它会创建一个长 pdf,所有页面都首尾相连,因此您需要将图像裁剪为所需的宽高比,并丢弃其余部分。以下是我最终使用的:
version :thumb_safari do #special version for safari and ios
process :resize_to_fit => [200,200]
process :convert => 'jpg'
process :paper_shape
def full_filename (for_file = model.logo.file)
super.chomp(File.extname(super)) + '.jpg'
end
end
version :thumb do #all browsers except safari
process :resize_to_fit => [200,200]
process :convert => 'jpg' #must convert to jpg before running paper shape
process :paper_shape
process :convert => 'jpg' #after running paper_shape it will default to original file type
def full_filename (for_file = model.logo.file)
super.chomp(File.extname(super)) + '.jpg'
end
end
def paper_shape
manipulate! do |img|
if img.rows*4 != img.columns*3
width=img.columns
height=img.columns/3*4
img.crop!(0,0,width,height,true)
else
img
end
end
end
在控制器/视图中,我使用了 useragent gem 并执行了以下操作:
documents_controller.rb
def index
@user_agent=UserAgent.parse(request.user_agent)
@search = Document.search(params[:q])
end
index.html.rb
<% if @user_agent.browser.downcase == 'safari' %>
<%= link_to(image_tag(doc.pdfdoc_url(:thumb_safari).to_s, :class=>"dropshadow", :size => "150x225"), doc.pdfdoc_url)%>
<% else %>
<%= link_to(image_tag(doc.pdfdoc_url(:thumb).to_s, :class=>"dropshadow", :size => "150x225"), doc.pdfdoc_url)%>
<% end %>
毫无疑问有更好的方法来做到这一点,但目前这是有效的。
@tanzeeb 提出的当前解决方案对于大多数图像/PDF 文件都很有效,并且操作函数是操作整个 pdf 的有用且动态的方法,但它太广泛了,在生成时不被认为是可行的方法缩略图,其主要目标是仅操作 pdf 的第一页。
此
manipulate!
代码强制在继续之前读取整个文件,并且稍后还会迭代整个文件。这对于生成缩略图来说是违反直觉的,并且可能会造成资源问题。
在
manipulate
内部有一个 &read_block
被传递到 ::Magic::Image.read/1
,并且可能用于更改传递到 read 本身的图像数据,其中一个 read_options
指定某一数据位来自current_path
。
尽管如此,CarrierWave 文档在描述其可能的用法方面过于肤浅,并且在描述其代码用法方面实际上是错误的。所以,这对我来说是一个死胡同。
我最终从
manipulate!
函数中获取了一堆代码以在我自己的上传器内部使用,其中我删除了一些在生成缩略图时未使用的功能。
# @doc Returns the first page of a file
version :thumb, :if => :thumbable? do
process :cover
process convert: "jpg"
def full_filename(filename = model.file.filename) = "#{filename.split(".").first}.jpg"
def style = :thumb
# @doc This is an overridden function from the `manipulate!` function defined in CarrierWaves library
# @doc I removed the ability to pass in options, or a block to the function to use in processing the image.
# @doc This seemed to be the route to go because there isn't many maintainers available on CarrierWave and the documentation is trash.
def cover
cache_file
push_frames(get_frames)
rescue ::Magick::ImageMagickError
raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.processing_error")
end
private
# @doc This will store the file available on the uploader in the cache, unless it is already cached.
def cache_file
cache_stored_file! unless cached?
end
# @doc This will utilize RMagick to create an image from an altered current_path variable
# @doc Create a new ImageList, and store the image created as the first frame
def get_frames
path = "#{current_path}[0]"
image = ::Magick::Image.read(path)
frames = ::Magick::ImageList.new
frames << image.first
end
# @doc This will persist the frames created as an ImageList into the file on the uploader, essentially replacing the original pdf with the modified pdf.
def push_frames(frames)
frames.write(current_path)
end
# @doc This will destroy the ImageList that is allocating memory.
def destroy_image(frames)
frames.try(:destroy!)
end
end