norman / has_image

A lightweight and opinionated but hackable library for attaching images to ActiveRecord models.

This URL has Read+Write access

gerrit (author)
Wed Oct 22 00:09:10 -0700 2008
commit  59f7224fcb6bb6bd8f170dc9cb00d57af04d33db
tree    e1ec3a318106a8c5022aab419f44da25cd000c71
parent  d7b057604aa0399afd51c89c3199644b860a2aea
has_image / lib / has_image / processor.rb
85e255d9 » Norman Clarke 2008-07-21 HasImage is now mostly kind... 1 require 'mini_magick'
84229d9f » Norman Clarke 2008-07-22 Implemented image validatio... 2
59fc89e6 » Norman Clarke 2008-07-20 Core processor and storage ... 3 module HasImage
4
52be8869 » Norman Clarke 2008-07-23 Worked on documentation. 5 # Image processing functionality for the HasImage gem.
59fc89e6 » Norman Clarke 2008-07-20 Core processor and storage ... 6 class Processor
7
85e255d9 » Norman Clarke 2008-07-21 HasImage is now mostly kind... 8 attr_accessor :options
ed83fc0d » Norman Clarke 2008-07-23 Improved organization of re... 9
10 class << self
34079570 » Norman Clarke 2008-07-25 Added thumbnail area sortin... 11
762c869d » Norman Clarke 2008-07-28 Added sorted thumbnail proc... 12 # "The form of an {extended geometry
13 # string}[http://www.imagemagick.org/script/command-line-options.php?#resize] is
14 # <width>x<height>{+-}<xoffset>{+-}<yoffset>{%}{!}{<}{>}"
15 def geometry_string_valid?(string)
16 string =~ /\A[\d]*x[\d]*([+-][0-9][+-][0-9])?[%@!<>^]?\Z/
17 end
34079570 » Norman Clarke 2008-07-25 Added thumbnail area sortin... 18
ed83fc0d » Norman Clarke 2008-07-23 Improved organization of re... 19 # Arg should be either a file, or a path. This runs ImageMagick's
20 # "identify" command and looks for an exit status indicating an error. If
21 # there is no error, then ImageMagick has identified the file as something
22 # it can work with and it will be converted to the desired output format.
23 def valid?(arg)
24 arg.close if arg.respond_to?(:close) && !arg.closed?
25 silence_stderr do
26 `identify #{arg.respond_to?(:path) ? arg.path : arg.to_s}`
27 $? == 0
28 end
d7b05760 » gerrit 2008-10-21 use width/height columns to... 29 end
30
ed83fc0d » Norman Clarke 2008-07-23 Improved organization of re... 31 end
d8172965 » Norman Clarke 2008-07-22 Tweaked README. Added logs ... 32
7c1ac7c5 » Norman Clarke 2008-07-24 Implemented uploaded file s... 33 # The constuctor should be invoked with the options set by has_image.
34 def initialize(options) # :nodoc:
d8172965 » Norman Clarke 2008-07-22 Tweaked README. Added logs ... 35 @options = options
36 end
59fc89e6 » Norman Clarke 2008-07-20 Core processor and storage ... 37
52be8869 » Norman Clarke 2008-07-23 Worked on documentation. 38 # Create the resized image, and transforms it to the desired output
c99267ce » gerrit 2008-10-14 refactored image resizing 39 # format if necessary.
40 #
41 # +size+ should be a valid ImageMagick {geometry string}[http://www.imagemagick.org/script/command-line-options.php#resize].
42 # +format+ should be an image format supported by ImageMagick, e.g. "PNG", "JPEG"
43 # yields the processed Image file as a file-like
44 def process(file, size=options[:resize_to], format=options[:convert_to])
fd08f541 » gerrit 2008-10-13 do conversion even if not r... 45 unless size.blank? || Processor.geometry_string_valid?(size)
39d0b37d » Norman Clarke 2008-07-29 Fixed typos and improved er... 46 raise InvalidGeometryError.new('"%s" is not a valid ImageMagick geometry string' % size)
47 end
c99267ce » gerrit 2008-10-14 refactored image resizing 48 with_image(file) do |image|
49 convert_image(image, format) if format
50 resize_image(image, size) if size
51 yield IO.read(image.path) if block_given?
52 image
59fc89e6 » Norman Clarke 2008-07-20 Core processor and storage ... 53 end
ed83fc0d » Norman Clarke 2008-07-23 Improved organization of re... 54 end
c99267ce » gerrit 2008-10-14 refactored image resizing 55 alias_method :resize, :process #Backwards-compat
ed83fc0d » Norman Clarke 2008-07-23 Improved organization of re... 56
59f7224f » gerrit 2008-10-22 moved measuring into the pr... 57 # Gets the given +dimension+ (width/height) from the image file at +path+
58 def measure(path, dimension)
59 MiniMagick::Image.from_file(path)[dimension.to_sym]
60 end
61
c99267ce » gerrit 2008-10-14 refactored image resizing 62 private
63 # operate on the image with MiniMagick
64 # yields a MiniMagick::Image object
65 def with_image(file)
66 path = file.respond_to?(:path) ? file.path : file
67 file.close if file.respond_to?(:close) && !file.closed?
68 silence_stderr do
ab753be7 » gerrit 2008-10-20 better expection handling 69 begin
70 image = MiniMagick::Image.from_file(path)
71 yield image
72 rescue MiniMagick::MiniMagickError
73 raise ProcessorError.new("#{path} doesn't look like an image file.")
74 ensure
75 image.tempfile.close! if defined?(image) && image
76 end
c99267ce » gerrit 2008-10-14 refactored image resizing 77 end
78 end
79
80 # +image+ should be a MiniMagick::Image and +size+ a Geometry String
52be8869 » Norman Clarke 2008-07-23 Worked on documentation. 81 # Image resizing is placed in a separate method for easy monkey-patching.
82 # This is intended to be invoked from resize, rather than directly.
7c1ac7c5 » Norman Clarke 2008-07-24 Implemented uploaded file s... 83 # By default, the following ImageMagick functionality is invoked:
84 # * auto-orient[http://www.imagemagick.org/script/command-line-options.php#auto-orient]
85 # * strip[http://www.imagemagick.org/script/command-line-options.php#strip]
86 # * resize[http://www.imagemagick.org/script/command-line-options.php#resize]
87 # * gravity[http://www.imagemagick.org/script/command-line-options.php#gravity]
88 # * extent[http://www.imagemagick.org/script/command-line-options.php#extent]
89 # * quality[http://www.imagemagick.org/script/command-line-options.php#quality]
c99267ce » gerrit 2008-10-14 refactored image resizing 90 def resize_image(image, size)
91 image.combine_options do |commands|
52be8869 » Norman Clarke 2008-07-23 Worked on documentation. 92 commands.send("auto-orient".to_sym)
93 commands.strip
762c869d » Norman Clarke 2008-07-28 Added sorted thumbnail proc... 94 # Fixed-dimension images
95 if size =~ /\A[\d]*x[\d]*!?\Z/
96 commands.resize "#{size}^"
97 commands.gravity "center"
98 commands.extent size
99 # Non-fixed-dimension images
100 else
101 commands.resize "#{size}"
102 end
52be8869 » Norman Clarke 2008-07-23 Worked on documentation. 103 commands.quality options[:output_quality]
104 end
105 end
106
c99267ce » gerrit 2008-10-14 refactored image resizing 107 def convert_image(image, format=options[:convert_to])
108 image.format(format) unless image[:format] == format
59fc89e6 » Norman Clarke 2008-07-20 Core processor and storage ... 109 end
110
111 end
112
113 end