Class: Paperclip::Geometry

Inherits:
Object
  • Object
show all
Defined in:
lib/paperclip/geometry.rb

Overview

Defines the geometry of an image.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width = nil, height = nil, modifier = nil) ⇒ Geometry

Gives a Geometry representing the given height and width



8
9
10
11
12
# File 'lib/paperclip/geometry.rb', line 8

def initialize width = nil, height = nil, modifier = nil
  @height = height.to_f
  @width  = width.to_f
  @modifier = modifier
end

Instance Attribute Details

#heightObject

Returns the value of attribute height.



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

def height
  @height
end

#modifierObject

Returns the value of attribute modifier.



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

def modifier
  @modifier
end

#widthObject

Returns the value of attribute width.



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

def width
  @width
end

Class Method Details

.from_file(file) ⇒ Object

Uses ImageMagick to determing the dimensions of a file, passed in as either a File or path. NOTE: (race cond) Do not reassign the ‘file’ variable inside this method as it is likely to be a Tempfile object, which would be eligible for file deletion when no longer referenced.



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/paperclip/geometry.rb', line 18

def self.from_file file
  file_path = file.respond_to?(:path) ? file.path : file
  raise(Paperclip::NotIdentifiedByImageMagickError.new("Cannot find the geometry of a file with a blank name")) if file_path.blank?
  geometry = begin
               Paperclip.run("identify", "-format %wx%h :file", :file => "#{file_path}[0]")
             rescue Cocaine::ExitStatusError
               ""
             rescue Cocaine::CommandNotFoundError => e
               raise Paperclip::CommandNotFoundError.new("Could not run the `identify` command. Please install ImageMagick.")
             end
  parse(geometry) ||
    raise(NotIdentifiedByImageMagickError.new("#{file_path} is not recognized by the 'identify' command."))
end

.parse(string) ⇒ Object

Parses a “WxH” formatted string, where W is the width and H is the height.



33
34
35
36
37
# File 'lib/paperclip/geometry.rb', line 33

def self.parse string
  if match = (string && string.match(/\b(\d*)x?(\d*)\b([\>\<\#\@\%^!])?/i))
    Geometry.new(*match[1,3])
  end
end

Instance Method Details

#aspectObject

The aspect ratio of the dimensions.



55
56
57
# File 'lib/paperclip/geometry.rb', line 55

def aspect
  width / height
end

#horizontal?Boolean

True if the dimensions represent a horizontal rectangle

Returns:

  • (Boolean)


45
46
47
# File 'lib/paperclip/geometry.rb', line 45

def horizontal?
  height < width
end

#inspectObject

Same as to_s



79
80
81
# File 'lib/paperclip/geometry.rb', line 79

def inspect
  to_s
end

#largerObject

Returns the larger of the two dimensions



60
61
62
# File 'lib/paperclip/geometry.rb', line 60

def larger
  [height, width].max
end

#new_dimensions_for(orig_width, orig_height) ⇒ Object

Adapted from attachment_fu. Attempts to get new dimensions for the current geometry string given these old dimensions. This doesn’t implement the aspect flag (!) or the area flag (@). PDI



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/paperclip/geometry.rb', line 105

def new_dimensions_for orig_width, orig_height
  new_width  = orig_width
  new_height = orig_height

  case self.modifier
    when '#'
      new_width  = self.width
      new_height = self.height
    when '%'
      scale_x = self.width.zero?  ? 100 : self.width
      scale_y = self.height.zero? ? self.width : self.height
      new_width    = scale_x.to_f * (orig_width.to_f  / 100.0)
      new_height   = scale_y.to_f * (orig_height.to_f / 100.0)
    when '<', '>', nil
      scale_factor =
        if new_width.zero? || new_height.zero?
          1.0
        else
          if self.width.nonzero? && self.height.nonzero?
            [self.width.to_f / new_width.to_f, self.height.to_f / new_height.to_f].min
          else
            self.width.nonzero? ? (self.width.to_f / new_width.to_f) : (self.height.to_f / new_height.to_f)
          end
        end
      new_width  = scale_factor * new_width.to_f
      new_height = scale_factor * new_height.to_f
      new_width  = orig_width  if self.modifier && new_width.send(self.modifier,  orig_width)
      new_height = orig_height if self.modifier && new_height.send(self.modifier, orig_height)
  end
  [new_width, new_height].collect! { |v| [v.round, 1].max }
end

#smallerObject

Returns the smaller of the two dimensions



65
66
67
# File 'lib/paperclip/geometry.rb', line 65

def smaller
  [height, width].min
end

#square?Boolean

True if the dimensions represent a square

Returns:

  • (Boolean)


40
41
42
# File 'lib/paperclip/geometry.rb', line 40

def square?
  height == width
end

#to_sObject

Returns the width and height in a format suitable to be passed to Geometry.parse



70
71
72
73
74
75
76
# File 'lib/paperclip/geometry.rb', line 70

def to_s
  s = ""
  s << width.to_i.to_s if width > 0
  s << "x#{height.to_i}" if height > 0
  s << modifier.to_s
  s
end

#transformation_to(dst, crop = false) ⇒ Object

Returns the scaling and cropping geometries (in string-based ImageMagick format) neccessary to transform this Geometry into the Geometry given. If crop is true, then it is assumed the destination Geometry will be the exact final resolution. In this case, the source Geometry is scaled so that an image containing the destination Geometry would be completely filled by the source image, and any overhanging image would be cropped. Useful for square thumbnail images. The cropping is weighted at the center of the Geometry.



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

def transformation_to dst, crop = false
  if crop
    ratio = Geometry.new( dst.width / self.width, dst.height / self.height )
    scale_geometry, scale = scaling(dst, ratio)
    crop_geometry         = cropping(dst, ratio, scale)
  else
    scale_geometry        = dst.to_s
  end

  [ scale_geometry, crop_geometry ]
end

#vertical?Boolean

True if the dimensions represent a vertical rectangle

Returns:

  • (Boolean)


50
51
52
# File 'lib/paperclip/geometry.rb', line 50

def vertical?
  height > width
end