dragonfly 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dragonfly might be problematic. Click here for more details.

Files changed (155) hide show
  1. data/{.specopts → .rspec} +0 -1
  2. data/.yardopts +6 -2
  3. data/Gemfile +14 -13
  4. data/History.md +47 -9
  5. data/README.md +25 -5
  6. data/Rakefile +37 -79
  7. data/VERSION +1 -1
  8. data/dragonfly.gemspec +140 -89
  9. data/extra_docs/Analysers.md +8 -48
  10. data/extra_docs/Configuration.md +40 -25
  11. data/extra_docs/Couch.md +49 -0
  12. data/extra_docs/DataStorage.md +94 -24
  13. data/extra_docs/Encoding.md +6 -35
  14. data/extra_docs/ExampleUseCases.md +113 -0
  15. data/extra_docs/GeneralUsage.md +7 -23
  16. data/extra_docs/Generators.md +15 -49
  17. data/extra_docs/Heroku.md +7 -8
  18. data/extra_docs/ImageMagick.md +126 -0
  19. data/extra_docs/MimeTypes.md +3 -3
  20. data/extra_docs/Models.md +163 -0
  21. data/extra_docs/Mongo.md +1 -4
  22. data/extra_docs/Processing.md +7 -60
  23. data/extra_docs/Rails2.md +3 -1
  24. data/extra_docs/Rails3.md +2 -10
  25. data/extra_docs/ServingRemotely.md +83 -0
  26. data/extra_docs/Sinatra.md +3 -3
  27. data/extra_docs/URLs.md +60 -33
  28. data/features/rails_3.0.5.feature +8 -0
  29. data/features/steps/rails_steps.rb +7 -18
  30. data/features/support/env.rb +10 -37
  31. data/features/support/setup.rb +32 -0
  32. data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
  33. data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
  34. data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
  35. data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -0
  36. data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
  37. data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
  38. data/fixtures/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
  39. data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
  40. data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
  41. data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
  42. data/irbrc.rb +2 -1
  43. data/lib/dragonfly.rb +7 -0
  44. data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
  45. data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
  46. data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
  47. data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
  48. data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
  49. data/lib/dragonfly/analyser.rb +0 -1
  50. data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
  51. data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
  52. data/lib/dragonfly/app.rb +64 -55
  53. data/lib/dragonfly/config/heroku.rb +1 -1
  54. data/lib/dragonfly/config/image_magick.rb +2 -37
  55. data/lib/dragonfly/config/rails.rb +5 -2
  56. data/lib/dragonfly/configurable.rb +115 -35
  57. data/lib/dragonfly/core_ext/object.rb +1 -1
  58. data/lib/dragonfly/core_ext/string.rb +1 -1
  59. data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
  60. data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
  61. data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
  62. data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
  63. data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
  64. data/lib/dragonfly/function_manager.rb +4 -2
  65. data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
  66. data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
  67. data/lib/dragonfly/image_magick/analyser.rb +51 -0
  68. data/lib/dragonfly/image_magick/config.rb +44 -0
  69. data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
  70. data/lib/dragonfly/image_magick/generator.rb +145 -0
  71. data/lib/dragonfly/image_magick/processor.rb +104 -0
  72. data/lib/dragonfly/image_magick/utils.rb +72 -0
  73. data/lib/dragonfly/image_magick_utils.rb +2 -79
  74. data/lib/dragonfly/job.rb +152 -90
  75. data/lib/dragonfly/middleware.rb +5 -19
  76. data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
  77. data/lib/dragonfly/rails/images.rb +15 -10
  78. data/lib/dragonfly/response.rb +26 -12
  79. data/lib/dragonfly/serializer.rb +1 -4
  80. data/lib/dragonfly/server.rb +103 -0
  81. data/lib/dragonfly/temp_object.rb +56 -101
  82. data/lib/dragonfly/url_mapper.rb +78 -0
  83. data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
  84. data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
  85. data/spec/dragonfly/analyser_spec.rb +1 -1
  86. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
  87. data/spec/dragonfly/app_spec.rb +35 -180
  88. data/spec/dragonfly/configurable_spec.rb +259 -18
  89. data/spec/dragonfly/core_ext/string_spec.rb +2 -2
  90. data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
  91. data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
  92. data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
  93. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
  94. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
  95. data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
  96. data/spec/dragonfly/function_manager_spec.rb +2 -2
  97. data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
  98. data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
  99. data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
  100. data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
  101. data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
  102. data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
  103. data/spec/dragonfly/job_builder_spec.rb +1 -1
  104. data/spec/dragonfly/job_definitions_spec.rb +1 -1
  105. data/spec/dragonfly/job_endpoint_spec.rb +26 -3
  106. data/spec/dragonfly/job_spec.rb +426 -208
  107. data/spec/dragonfly/loggable_spec.rb +2 -2
  108. data/spec/dragonfly/middleware_spec.rb +5 -26
  109. data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
  110. data/spec/dragonfly/serializer_spec.rb +1 -14
  111. data/spec/dragonfly/server_spec.rb +261 -0
  112. data/spec/dragonfly/simple_cache_spec.rb +1 -1
  113. data/spec/dragonfly/temp_object_spec.rb +84 -130
  114. data/spec/dragonfly/url_mapper_spec.rb +130 -0
  115. data/spec/functional/deprecations_spec.rb +51 -0
  116. data/spec/functional/image_magick_app_spec.rb +27 -0
  117. data/spec/functional/model_urls_spec.rb +85 -0
  118. data/spec/functional/remote_on_the_fly_spec.rb +51 -0
  119. data/spec/functional/to_response_spec.rb +31 -0
  120. data/spec/spec_helper.rb +12 -22
  121. data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
  122. data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
  123. data/spec/support/simple_matchers.rb +53 -0
  124. data/yard/handlers/configurable_attr_handler.rb +2 -2
  125. data/yard/templates/default/fulldoc/html/css/common.css +12 -10
  126. data/yard/templates/default/layout/html/layout.erb +6 -0
  127. metadata +267 -308
  128. data/Gemfile.rails.2.3.5 +0 -20
  129. data/features/3.0.3.feature +0 -8
  130. data/features/rails_2.3.5.feature +0 -7
  131. data/fixtures/files/app/models/album.rb +0 -3
  132. data/fixtures/files/app/views/albums/new.html.erb +0 -4
  133. data/fixtures/files/features/manage_album_images.feature +0 -12
  134. data/fixtures/rails_2.3.5/template.rb +0 -10
  135. data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
  136. data/lib/dragonfly/config/r_magick.rb +0 -46
  137. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
  138. data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
  139. data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
  140. data/lib/dragonfly/r_magick_utils.rb +0 -48
  141. data/lib/dragonfly/simple_endpoint.rb +0 -76
  142. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
  143. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
  144. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
  145. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
  146. data/spec/dragonfly/config/r_magick_spec.rb +0 -29
  147. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
  148. data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
  149. data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
  150. data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
  151. data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
  152. data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
  153. data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
  154. data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
  155. data/spec/simple_matchers.rb +0 -44
@@ -1,20 +0,0 @@
1
- source :rubygems
2
-
3
- group :development, :test, :cucumber do
4
- gem 'capybara'
5
- gem 'cucumber', '0.8.5'
6
- gem 'cucumber-rails'
7
- gem 'database_cleaner', '>= 0.5.0'
8
- gem 'gherkin', '2.1.4'
9
- gem 'nokogiri', '1.5.0.beta.2'
10
- gem 'rack-cache', :require => nil
11
- gem 'rails', '2.3.5', :require => nil
12
- gem 'rspec', '~> 1.3'
13
- if RUBY_PLATFORM == "java"
14
- gem "jdbc-sqlite3"
15
- gem "activerecord-jdbcsqlite3-adapter"
16
- gem "jruby-openssl"
17
- else
18
- gem 'sqlite3-ruby', '1.3.0' # 1.3.1 segfaults on Ruby 1.9.2
19
- end
20
- end
@@ -1,8 +0,0 @@
1
- Feature: champion uses dragonfly in his Rails 3.0.3 application
2
- In order to be a champion
3
- A user uses dragonfly in his Rails 3.0.3 application
4
-
5
- Scenario: Set up dragonfly using initializer
6
- Given a Rails 3.0.3 application set up for using dragonfly
7
- Then the manage_album_images cucumber features in my Rails 3.0.3 app should pass
8
- And the text_images cucumber features in my Rails 3.0.3 app should pass
@@ -1,7 +0,0 @@
1
- Feature: champion uses dragonfly in his Rails 2.3.5 application
2
- In order to be a champion
3
- A user uses dragonfly in his Rails 2.3.5 application
4
-
5
- Scenario: Set up dragonfly using the provided initializer
6
- Given a Rails 2.3.5 application set up for using dragonfly
7
- Then the manage_album_images cucumber features in my Rails 2.3.5 app should pass
@@ -1,3 +0,0 @@
1
- class Album < ActiveRecord::Base
2
- image_accessor :cover_image
3
- end
@@ -1,4 +0,0 @@
1
- <% form_for @album, :html => {:multipart => true} do |f| %>
2
- <%= f.file_field :cover_image %>
3
- <%= f.submit :value => 'Create' %>
4
- <% end %>
@@ -1,12 +0,0 @@
1
- Feature: champion adds cover images to his albums
2
- In order to be a champion
3
- A user adds an image to his album
4
-
5
- Scenario: Add and view image
6
- When I go to the new album page
7
- And I attach the file "../../../samples/beach.png" to "album[cover_image]"
8
- And I press "Create"
9
- Then I should see "successfully created"
10
- And I should see "Look at this cover image!"
11
- When I look at the generated beach image
12
- And I should see a PNG image of size 200x100
@@ -1,10 +0,0 @@
1
- gem 'rack-cache', :lib => 'rack/cache'
2
- gem 'cucumber'
3
- generate 'cucumber'
4
-
5
- generate 'scaffold albums cover_image_uid:string'
6
- rake 'db:migrate'
7
-
8
- # Copy over all files from the template dir
9
- files_dir = File.expand_path(File.dirname(__FILE__) + '/../../files')
10
- run "cp -r #{files_dir}/** ."
@@ -1,63 +0,0 @@
1
- require 'RMagick'
2
-
3
- module Dragonfly
4
- module Analysis
5
- class RMagickAnalyser
6
-
7
- include RMagickUtils
8
- include Configurable
9
-
10
- configurable_attr :use_filesystem, true
11
-
12
- def width(temp_object)
13
- ping_rmagick_image(temp_object) do |image|
14
- image.columns
15
- end
16
- end
17
-
18
- def height(temp_object)
19
- ping_rmagick_image(temp_object) do |image|
20
- image.rows
21
- end
22
- end
23
-
24
- def aspect_ratio(temp_object)
25
- ping_rmagick_image(temp_object) do |image|
26
- image.columns.to_f / image.rows
27
- end
28
- end
29
-
30
- def portrait?(temp_object)
31
- ping_rmagick_image(temp_object) do |image|
32
- image.columns <= image.rows
33
- end
34
- end
35
-
36
- def landscape?(temp_object)
37
- ping_rmagick_image(temp_object) do |image|
38
- image.columns >= image.rows
39
- end
40
- end
41
-
42
- def depth(temp_object)
43
- rmagick_image(temp_object) do |image|
44
- image.depth
45
- end
46
- end
47
-
48
- def number_of_colours(temp_object)
49
- rmagick_image(temp_object) do |image|
50
- image.number_colors
51
- end
52
- end
53
- alias number_of_colors number_of_colours
54
-
55
- def format(temp_object)
56
- ping_rmagick_image(temp_object) do |image|
57
- image.format.downcase.to_sym
58
- end
59
- end
60
-
61
- end
62
- end
63
- end
@@ -1,46 +0,0 @@
1
- module Dragonfly
2
- module Config
3
-
4
- # RMagick is a saved configuration for Dragonfly apps, which does the following:
5
- # - registers an rmagick analyser
6
- # - registers an rmagick processor
7
- # - registers an rmagick encoder
8
- # - adds thumb shortcuts like '280x140!', etc.
9
- # Look at the source code for apply_configuration to see exactly how it configures the app.
10
- module RMagick
11
-
12
- def self.apply_configuration(app, opts={})
13
- use_filesystem = opts.has_key?(:use_filesystem) ? opts[:use_filesystem] : true
14
- app.configure do |c|
15
- c.analyser.register(Analysis::RMagickAnalyser) do |a|
16
- a.use_filesystem = use_filesystem
17
- end
18
- c.processor.register(Processing::RMagickProcessor) do |p|
19
- p.use_filesystem = use_filesystem
20
- end
21
- c.encoder.register(Encoding::RMagickEncoder) do |e|
22
- e.use_filesystem = use_filesystem
23
- end
24
- c.generator.register(Generation::RMagickGenerator) do |g|
25
- g.use_filesystem = use_filesystem
26
- end
27
- c.job :thumb do |geometry, format|
28
- process :thumb, geometry
29
- encode format if format
30
- end
31
- c.job :gif do
32
- encode :gif
33
- end
34
- c.job :jpg do
35
- encode :jpg
36
- end
37
- c.job :png do
38
- encode :png
39
- end
40
- end
41
-
42
- end
43
-
44
- end
45
- end
46
- end
@@ -1,23 +0,0 @@
1
- module Dragonfly
2
- module Generation
3
-
4
- # HashWithCssStyleKeys is solely for being able to access a hash
5
- # which has css-style keys (e.g. 'font-size') with the underscore
6
- # symbol version
7
- # @example
8
- # opts = {'font-size' => '23px', :color => 'white'}
9
- # opts = HashWithCssStyleKeys[opts]
10
- # opts[:font_size] # ===> '23px'
11
- # opts[:color] # ===> 'white'
12
- class HashWithCssStyleKeys < Hash
13
- def [](key)
14
- super || (
15
- str_key = key.to_s
16
- css_key = str_key.gsub('_','-')
17
- super(str_key) || super(css_key) || super(css_key.to_sym)
18
- )
19
- end
20
- end
21
-
22
- end
23
- end
@@ -1,155 +0,0 @@
1
- require 'RMagick'
2
-
3
- module Dragonfly
4
- module Generation
5
- class RMagickGenerator
6
-
7
- FONT_STYLES = {
8
- 'normal' => Magick::NormalStyle,
9
- 'italic' => Magick::ItalicStyle,
10
- 'oblique' => Magick::ObliqueStyle
11
- }
12
-
13
- FONT_STRETCHES = {
14
- 'normal' => Magick::NormalStretch,
15
- 'semi-condensed' => Magick::SemiCondensedStretch,
16
- 'condensed' => Magick::CondensedStretch,
17
- 'extra-condensed' => Magick::ExtraCondensedStretch,
18
- 'ultra-condensed' => Magick::UltraCondensedStretch,
19
- 'semi-expanded' => Magick::SemiExpandedStretch,
20
- 'expanded' => Magick::ExpandedStretch,
21
- 'extra-expanded' => Magick::ExtraExpandedStretch,
22
- 'ultra-expanded' => Magick::UltraExpandedStretch
23
- }
24
-
25
- FONT_WEIGHTS = {
26
- 'normal' => Magick::NormalWeight,
27
- 'bold' => Magick::BoldWeight,
28
- 'bolder' => Magick::BolderWeight,
29
- 'lighter' => Magick::LighterWeight,
30
- '100' => 100,
31
- '200' => 200,
32
- '300' => 300,
33
- '400' => 400,
34
- '500' => 500,
35
- '600' => 600,
36
- '700' => 700,
37
- '800' => 800,
38
- '900' => 900
39
- }
40
-
41
- include RMagickUtils
42
- include Configurable
43
- configurable_attr :use_filesystem, true
44
-
45
- def plasma(width, height, format='png')
46
- image = Magick::Image.read("plasma:fractal"){self.size = "#{width}x#{height}"}.first
47
- image.format = format.to_s
48
- content = use_filesystem ? write_to_tempfile(image) : image.to_blob
49
- image.destroy!
50
- [
51
- content,
52
- {:format => format.to_sym, :name => "plasma.#{format}"}
53
- ]
54
- end
55
-
56
- def text(text_string, opts={})
57
- opts = HashWithCssStyleKeys[opts]
58
-
59
- draw = Magick::Draw.new
60
- draw.gravity = Magick::CenterGravity
61
- draw.text_antialias = true
62
-
63
- # Font size
64
- font_size = (opts[:font_size] || 12).to_i
65
-
66
- # Scale up the text for better quality -
67
- # it will be reshrunk at the end
68
- s = scale_factor_for(font_size)
69
-
70
- # Settings
71
- draw.pointsize = font_size * s
72
- draw.font = opts[:font] if opts[:font]
73
- draw.font_family = opts[:font_family] if opts[:font_family]
74
- draw.fill = opts[:color] if opts[:color]
75
- draw.stroke = opts[:stroke_color] if opts[:stroke_color]
76
- draw.font_style = FONT_STYLES[opts[:font_style]] if opts[:font_style]
77
- draw.font_stretch = FONT_STRETCHES[opts[:font_stretch]] if opts[:font_stretch]
78
- draw.font_weight = FONT_WEIGHTS[opts[:font_weight]] if opts[:font_weight]
79
-
80
- # Padding
81
- # NB the values are scaled up by the scale factor
82
- pt, pr, pb, pl = parse_padding_string(opts[:padding]) if opts[:padding]
83
- padding_top = (opts[:padding_top] || pt || 0) * s
84
- padding_right = (opts[:padding_right] || pr || 0) * s
85
- padding_bottom = (opts[:padding_bottom] || pb || 0) * s
86
- padding_left = (opts[:padding_left] || pl || 0) * s
87
-
88
- # Calculate (scaled up) dimensions
89
- metrics = draw.get_type_metrics(text_string)
90
- width, height = metrics.width, metrics.height
91
-
92
- scaled_up_width = padding_left + width + padding_right
93
- scaled_up_height = padding_top + height + padding_bottom
94
-
95
- # Draw the background
96
- image = Magick::Image.new(scaled_up_width, scaled_up_height){
97
- self.background_color = opts[:background_color] || 'transparent'
98
- }
99
- # Draw the text
100
- draw.annotate(image, width, height, padding_left, padding_top, text_string)
101
-
102
- # Scale back down again
103
- image.scale!(1/s)
104
-
105
- format = opts[:format] || :png
106
- image.format = format.to_s
107
-
108
- # Output image either as a string or a tempfile
109
- content = use_filesystem ? write_to_tempfile(image) : image.to_blob
110
- image.destroy!
111
- [
112
- content,
113
- {:format => format, :name => "text.#{format}"}
114
- ]
115
- end
116
-
117
- private
118
-
119
- # Use css-style padding declaration, i.e.
120
- # 10 (all sides)
121
- # 10 5 (top/bottom, left/right)
122
- # 10 5 10 (top, left/right, bottom)
123
- # 10 5 10 5 (top, right, bottom, left)
124
- def parse_padding_string(str)
125
- padding_parts = str.gsub('px','').split(/\s+/).map{|px| px.to_i}
126
- case padding_parts.size
127
- when 1
128
- p = padding_parts.first
129
- [p,p,p,p]
130
- when 2
131
- p,q = padding_parts
132
- [p,q,p,q]
133
- when 3
134
- p,q,r = padding_parts
135
- [p,q,r,q]
136
- when 4
137
- padding_parts
138
- else raise ArgumentError, "Couldn't parse padding string '#{str}' - should be a css-style string"
139
- end
140
- end
141
-
142
- def scale_factor_for(font_size)
143
- # Scale approximately to 64 if below
144
- min_size = 64
145
- if font_size < min_size
146
- (min_size.to_f / font_size).ceil
147
- else
148
- 1
149
- end.to_f
150
- end
151
-
152
- end
153
-
154
- end
155
- end
@@ -1,126 +0,0 @@
1
- require 'RMagick'
2
-
3
- module Dragonfly
4
- module Processing
5
- class RMagickProcessor
6
-
7
- GRAVITIES = {
8
- 'nw' => Magick::NorthWestGravity,
9
- 'n' => Magick::NorthGravity,
10
- 'ne' => Magick::NorthEastGravity,
11
- 'w' => Magick::WestGravity,
12
- 'c' => Magick::CenterGravity,
13
- 'e' => Magick::EastGravity,
14
- 'sw' => Magick::SouthWestGravity,
15
- 's' => Magick::SouthGravity,
16
- 'se' => Magick::SouthEastGravity
17
- }
18
-
19
- # Geometry string patterns
20
- RESIZE_GEOMETRY = /^\d*x\d*[><%^!]?$|^\d+@$/ # e.g. '300x200!'
21
- CROPPED_RESIZE_GEOMETRY = /^(\d+)x(\d+)#(\w{1,2})?$/ # e.g. '20x50#ne'
22
- CROP_GEOMETRY = /^(\d+)x(\d+)([+-]\d+)?([+-]\d+)?(\w{1,2})?$/ # e.g. '30x30+10+10'
23
- THUMB_GEOMETRY = Regexp.union RESIZE_GEOMETRY, CROPPED_RESIZE_GEOMETRY, CROP_GEOMETRY
24
-
25
- include RMagickUtils
26
- include Configurable
27
-
28
- configurable_attr :use_filesystem, true
29
-
30
- def crop(temp_object, opts={})
31
- x = opts[:x].to_i
32
- y = opts[:y].to_i
33
- gravity = GRAVITIES[opts[:gravity]] || Magick::ForgetGravity
34
- width = opts[:width].to_i
35
- height = opts[:height].to_i
36
-
37
- rmagick_image(temp_object) do |image|
38
- # RMagick throws an error if the cropping area is bigger than the image,
39
- # when the gravity is something other than nw
40
- width = image.columns - x if x + width > image.columns
41
- height = image.rows - y if y + height > image.rows
42
- image.crop(gravity, x, y, width, height)
43
- end
44
- end
45
-
46
- def flip(temp_object)
47
- rmagick_image(temp_object) do |image|
48
- image.flip!
49
- end
50
- end
51
-
52
- def flop(temp_object)
53
- rmagick_image(temp_object) do |image|
54
- image.flop!
55
- end
56
- end
57
-
58
- def greyscale(temp_object, opts={})
59
- depth = opts[:depth] || 256
60
- rmagick_image(temp_object) do |image|
61
- image.quantize(depth, Magick::GRAYColorspace)
62
- end
63
- end
64
- alias grayscale greyscale
65
-
66
- def resize(temp_object, geometry)
67
- rmagick_image(temp_object) do |image|
68
- image.change_geometry!(geometry) do |cols, rows, img|
69
- img.resize!(cols, rows)
70
- end
71
- end
72
- end
73
-
74
- def resize_and_crop(temp_object, opts={})
75
- rmagick_image(temp_object) do |image|
76
-
77
- width = opts[:width] ? opts[:width].to_i : image.columns
78
- height = opts[:height] ? opts[:height].to_i : image.rows
79
- gravity = GRAVITIES[opts[:gravity]] || Magick::CenterGravity
80
-
81
- image.crop_resized(width, height, gravity)
82
- end
83
- end
84
-
85
- def rotate(temp_object, amount, opts={})
86
- args = [amount.to_f]
87
- args << opts[:qualifier] if opts[:qualifier]
88
- rmagick_image(temp_object) do |image|
89
- image.background_color = opts[:background_colour] if opts[:background_colour]
90
- image.background_color = opts[:background_color] if opts[:background_color]
91
- image.rotate(*args) || temp_object
92
- end
93
- end
94
-
95
- def thumb(temp_object, geometry)
96
- case geometry
97
- when RESIZE_GEOMETRY
98
- resize(temp_object, geometry)
99
- when CROPPED_RESIZE_GEOMETRY
100
- resize_and_crop(temp_object, :width => $1, :height => $2, :gravity => $3)
101
- when CROP_GEOMETRY
102
- crop(temp_object,
103
- :width => $1,
104
- :height => $2,
105
- :x => $3,
106
- :y => $4,
107
- :gravity => $5
108
- )
109
- else raise ArgumentError, "Didn't recognise the geometry string #{geometry}"
110
- end
111
- end
112
-
113
- def vignette(temp_object, opts={})
114
- x = opts[:x].to_f || temp_object.width * 0.1
115
- y = opts[:y].to_f || temp_object.height * 0.1
116
- radius = opts[:radius].to_f || 0.0
117
- sigma = opts[:sigma].to_f || 10.0
118
-
119
- rmagick_image(temp_object) do |image|
120
- image.vignette(x, y, radius, sigma)
121
- end
122
- end
123
-
124
- end
125
- end
126
- end