Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
Allow user to specify frame_index for videos or PDFs
Browse files Browse the repository at this point in the history
[closes #2155]
  • Loading branch information
jacobbullock authored and tute committed Aug 23, 2016
1 parent fa58ec3 commit 8b16370
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
18 changes: 14 additions & 4 deletions lib/paperclip/thumbnail.rb
Expand Up @@ -3,10 +3,11 @@ module Paperclip
class Thumbnail < Processor

attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options,
:source_file_options, :animated, :auto_orient
:source_file_options, :animated, :auto_orient, :frame_index

# List of formats that we need to preserve animation
ANIMATED_FORMATS = %w(gif)
MULTI_FRAME_FORMATS = %w(.mkv .avi .mp4 .mov .mpg .mpeg .gif)

# Creates a Thumbnail object set to work on the +file+ given. It
# will attempt to transform the image into one defined by +target_geometry+
Expand All @@ -25,6 +26,7 @@ class Thumbnail < Processor
# +whiny+ - whether to raise an error when processing fails. Defaults to true
# +format+ - the desired filename extension
# +animated+ - whether to merge all the layers in the image. Defaults to true
# +frame_index+ - the frame index of the source file to render as the thumbnail
def initialize(file, options = {}, attachment = nil)
super

Expand All @@ -41,12 +43,12 @@ def initialize(file, options = {}, attachment = nil)
if @auto_orient && @current_geometry.respond_to?(:auto_orient)
@current_geometry.auto_orient
end

@source_file_options = @source_file_options.split(/\s+/) if @source_file_options.respond_to?(:split)
@convert_options = @convert_options.split(/\s+/) if @convert_options.respond_to?(:split)

@current_format = File.extname(@file.path)
@basename = File.basename(@file.path, @current_format)
@frame_index = multi_frame_format? ? options.fetch(:frame_index, 0) : 0
end

# Returns true if the +target_geometry+ is meant to crop.
Expand Down Expand Up @@ -76,7 +78,12 @@ def make

parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")

success = convert(parameters, :source => "#{File.expand_path(src.path)}#{'[0]' unless animated?}", :dest => File.expand_path(dst.path))
frame = animated? ? "" : "[#{@frame_index}]"
convert(
parameters,
source: "#{File.expand_path(src.path)}#{frame}",
dest: File.expand_path(dst.path),
)
rescue Cocaine::ExitStatusError => e
raise Paperclip::Error, "There was an error processing the thumbnail for #{@basename}" if @whiny
rescue Cocaine::CommandNotFoundError => e
Expand All @@ -101,7 +108,10 @@ def transformation_command

protected

# Return true if the format is animated
def multi_frame_format?
MULTI_FRAME_FORMATS.include? @current_format
end

def animated?
@animated && (ANIMATED_FORMATS.include?(@format.to_s) || @format.blank?) && identified_as_animated?
end
Expand Down
35 changes: 35 additions & 0 deletions spec/paperclip/thumbnail_spec.rb
Expand Up @@ -480,6 +480,41 @@ def to_s
assert_equal "50x50", `#{cmd}`.chomp
end
end

context "with a specified frame_index" do
before do
@thumb = Paperclip::Thumbnail.new(
@file,
geometry: "50x50",
frame_index: 5,
format: :jpg,
)
end

it "creates the thumbnail from the frame index when sent #make" do
@thumb.make
assert_equal 5, @thumb.frame_index
end
end

context "with a specified frame_index out of bounds" do
before do
@thumb = Paperclip::Thumbnail.new(
@file,
geometry: "50x50",
frame_index: 20,
format: :jpg,
)
end

it "errors when trying to create the thumbnail" do
assert_raises(Paperclip::Error) do
silence_stream(STDERR) do
@thumb.make
end
end
end
end
end

context "with a really long file name" do
Expand Down

0 comments on commit 8b16370

Please sign in to comment.