Class: Paperclip::Thumbnail

Inherits:
Processor show all
Defined in:
lib/paperclip/thumbnail.rb

Overview

Handles thumbnailing images that are uploaded.

Constant Summary collapse

ANIMATED_FORMATS =

List of formats that we need to preserve animation

%w(gif)

Instance Attribute Summary collapse

Attributes inherited from Processor

#attachment, #file, #options

Instance Method Summary collapse

Methods inherited from Processor

#convert, #identify, make

Constructor Details

#initialize(file, options = {}, attachment = nil) ⇒ 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

Options include:

+geometry+ - the desired width and height of the thumbnail (required)
+file_geometry_parser+ - an object with a method named +from_file+ that takes an image file and produces its geometry and a +transformation_to+. Defaults to Paperclip::Geometry
+string_geometry_parser+ - an object with a method named +parse+ that takes a string and produces an object with +width+, +height+, and +to_s+ accessors. Defaults to Paperclip::Geometry
+source_file_options+ - flags passed to the +convert+ command that influence how the source file is read
+convert_options+ - flags passed to the +convert+ command that influence how the image is processed
+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


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/paperclip/thumbnail.rb', line 28

def initialize(file, options = {}, attachment = nil)
  super

  geometry             = options[:geometry].to_s
  @crop                = geometry[-1,1] == '#'
  @target_geometry     = options.fetch(:string_geometry_parser, Geometry).parse(geometry)
  @current_geometry    = options.fetch(:file_geometry_parser, Geometry).from_file(@file)
  @source_file_options = options[:source_file_options]
  @convert_options     = options[:convert_options]
  @whiny               = options.fetch(:whiny, true)
  @format              = options[:format]
  @animated            = options.fetch(:animated, true)
  @auto_orient         = options.fetch(:auto_orient, true)
  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)
end

Instance Attribute Details

#animatedObject

Returns the value of attribute animated.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def animated
  @animated
end

#auto_orientObject

Returns the value of attribute auto_orient.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def auto_orient
  @auto_orient
end

#convert_optionsObject

Returns the value of attribute convert_options.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def convert_options
  @convert_options
end

#current_geometryObject

Returns the value of attribute current_geometry.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def current_geometry
  @current_geometry
end

#formatObject

Returns the value of attribute format.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def format
  @format
end

#source_file_optionsObject

Returns the value of attribute source_file_options.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def source_file_options
  @source_file_options
end

#target_geometryObject

Returns the value of attribute target_geometry.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def target_geometry
  @target_geometry
end

#whinyObject

Returns the value of attribute whiny.



5
6
7
# File 'lib/paperclip/thumbnail.rb', line 5

def whiny
  @whiny
end

Instance Method Details

#convert_options?Boolean

Returns true if the image is meant to make use of additional convert options.

Returns:

  • (Boolean)


58
59
60
# File 'lib/paperclip/thumbnail.rb', line 58

def convert_options?
  !@convert_options.nil? && !@convert_options.empty?
end

#crop?Boolean

Returns true if the target_geometry is meant to crop.

Returns:

  • (Boolean)


53
54
55
# File 'lib/paperclip/thumbnail.rb', line 53

def crop?
  @crop
end

#makeObject

Performs the conversion of the file into a thumbnail. Returns the Tempfile that contains the new image.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/paperclip/thumbnail.rb', line 64

def make
  src = @file
  filename = [@basename, @format ? ".#{@format}" : ""].join
  dst = TempfileFactory.new.generate(filename)

  begin
    parameters = []
    parameters << source_file_options
    parameters << ":source"
    parameters << transformation_command
    parameters << convert_options
    parameters << ":dest"

    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))
  rescue Cocaine::ExitStatusError => e
    raise Paperclip::Error, "There was an error processing the thumbnail for #{@basename}" if @whiny
  rescue Cocaine::CommandNotFoundError => e
    raise Paperclip::Errors::CommandNotFoundError.new("Could not run the `convert` command. Please install ImageMagick.")
  end

  dst
end

#transformation_commandObject

Returns the command ImageMagick’s convert needs to transform the image into the thumbnail.



91
92
93
94
95
96
97
98
99
100
# File 'lib/paperclip/thumbnail.rb', line 91

def transformation_command
  scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
  trans = []
  trans << "-coalesce" if animated?
  trans << "-auto-orient" if auto_orient
  trans << "-resize" << %["#{scale}"] unless scale.nil? || scale.empty?
  trans << "-crop" << %["#{crop}"] << "+repage" if crop
  trans << '-layers "optimize"' if animated?
  trans
end