fog-dragonfly 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. data/.specopts +2 -0
  2. data/.yardopts +23 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.rails.2.3.5 +14 -0
  5. data/History.md +266 -0
  6. data/LICENSE +20 -0
  7. data/README.md +88 -0
  8. data/Rakefile +92 -0
  9. data/VERSION +1 -0
  10. data/config.ru +13 -0
  11. data/docs.watchr +1 -0
  12. data/dragonfly.gemspec +293 -0
  13. data/extra_docs/Analysers.md +108 -0
  14. data/extra_docs/Caching.md +23 -0
  15. data/extra_docs/Configuration.md +138 -0
  16. data/extra_docs/DataStorage.md +136 -0
  17. data/extra_docs/Encoding.md +96 -0
  18. data/extra_docs/GeneralUsage.md +121 -0
  19. data/extra_docs/Generators.md +102 -0
  20. data/extra_docs/Heroku.md +50 -0
  21. data/extra_docs/Index.md +36 -0
  22. data/extra_docs/MimeTypes.md +40 -0
  23. data/extra_docs/Models.md +266 -0
  24. data/extra_docs/Mongo.md +45 -0
  25. data/extra_docs/Processing.md +130 -0
  26. data/extra_docs/Rack.md +52 -0
  27. data/extra_docs/Rails2.md +55 -0
  28. data/extra_docs/Rails3.md +62 -0
  29. data/extra_docs/Sinatra.md +25 -0
  30. data/extra_docs/URLs.md +169 -0
  31. data/features/3.0.3.feature +8 -0
  32. data/features/images.feature +47 -0
  33. data/features/no_processing.feature +14 -0
  34. data/features/rails_2.3.5.feature +7 -0
  35. data/features/steps/common_steps.rb +8 -0
  36. data/features/steps/dragonfly_steps.rb +66 -0
  37. data/features/steps/rails_steps.rb +39 -0
  38. data/features/support/env.rb +40 -0
  39. data/fixtures/files/app/models/album.rb +3 -0
  40. data/fixtures/files/app/views/albums/new.html.erb +4 -0
  41. data/fixtures/files/app/views/albums/show.html.erb +4 -0
  42. data/fixtures/files/config/initializers/dragonfly.rb +4 -0
  43. data/fixtures/files/features/manage_album_images.feature +12 -0
  44. data/fixtures/files/features/step_definitions/image_steps.rb +15 -0
  45. data/fixtures/files/features/support/paths.rb +15 -0
  46. data/fixtures/files/features/text_images.feature +7 -0
  47. data/fixtures/rails_2.3.5/template.rb +10 -0
  48. data/fixtures/rails_3.0.3/template.rb +20 -0
  49. data/irbrc.rb +17 -0
  50. data/lib/dragonfly.rb +45 -0
  51. data/lib/dragonfly/active_model_extensions.rb +13 -0
  52. data/lib/dragonfly/active_model_extensions/attachment.rb +169 -0
  53. data/lib/dragonfly/active_model_extensions/class_methods.rb +45 -0
  54. data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
  55. data/lib/dragonfly/active_model_extensions/validations.rb +37 -0
  56. data/lib/dragonfly/analyser.rb +59 -0
  57. data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
  58. data/lib/dragonfly/analysis/image_magick_analyser.rb +47 -0
  59. data/lib/dragonfly/analysis/r_magick_analyser.rb +63 -0
  60. data/lib/dragonfly/app.rb +182 -0
  61. data/lib/dragonfly/config/heroku.rb +19 -0
  62. data/lib/dragonfly/config/image_magick.rb +41 -0
  63. data/lib/dragonfly/config/r_magick.rb +46 -0
  64. data/lib/dragonfly/config/rails.rb +17 -0
  65. data/lib/dragonfly/configurable.rb +119 -0
  66. data/lib/dragonfly/core_ext/object.rb +8 -0
  67. data/lib/dragonfly/core_ext/string.rb +9 -0
  68. data/lib/dragonfly/core_ext/symbol.rb +9 -0
  69. data/lib/dragonfly/data_storage.rb +9 -0
  70. data/lib/dragonfly/data_storage/file_data_store.rb +114 -0
  71. data/lib/dragonfly/data_storage/mongo_data_store.rb +82 -0
  72. data/lib/dragonfly/data_storage/s3data_store.rb +115 -0
  73. data/lib/dragonfly/encoder.rb +13 -0
  74. data/lib/dragonfly/encoding/image_magick_encoder.rb +57 -0
  75. data/lib/dragonfly/encoding/r_magick_encoder.rb +61 -0
  76. data/lib/dragonfly/function_manager.rb +69 -0
  77. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +23 -0
  78. data/lib/dragonfly/generation/image_magick_generator.rb +140 -0
  79. data/lib/dragonfly/generation/r_magick_generator.rb +155 -0
  80. data/lib/dragonfly/generator.rb +9 -0
  81. data/lib/dragonfly/image_magick_utils.rb +81 -0
  82. data/lib/dragonfly/job.rb +371 -0
  83. data/lib/dragonfly/job_builder.rb +39 -0
  84. data/lib/dragonfly/job_definitions.rb +26 -0
  85. data/lib/dragonfly/job_endpoint.rb +15 -0
  86. data/lib/dragonfly/loggable.rb +28 -0
  87. data/lib/dragonfly/middleware.rb +34 -0
  88. data/lib/dragonfly/processing/image_magick_processor.rb +99 -0
  89. data/lib/dragonfly/processing/r_magick_processor.rb +126 -0
  90. data/lib/dragonfly/processor.rb +9 -0
  91. data/lib/dragonfly/r_magick_utils.rb +48 -0
  92. data/lib/dragonfly/rails/images.rb +22 -0
  93. data/lib/dragonfly/response.rb +82 -0
  94. data/lib/dragonfly/routed_endpoint.rb +40 -0
  95. data/lib/dragonfly/serializer.rb +32 -0
  96. data/lib/dragonfly/simple_cache.rb +23 -0
  97. data/lib/dragonfly/simple_endpoint.rb +63 -0
  98. data/lib/dragonfly/temp_object.rb +220 -0
  99. data/samples/beach.png +0 -0
  100. data/samples/egg.png +0 -0
  101. data/samples/round.gif +0 -0
  102. data/samples/sample.docx +0 -0
  103. data/samples/taj.jpg +0 -0
  104. data/spec/argument_matchers.rb +19 -0
  105. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
  106. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
  107. data/spec/dragonfly/active_model_extensions/model_spec.rb +723 -0
  108. data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
  109. data/spec/dragonfly/analyser_spec.rb +123 -0
  110. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +57 -0
  111. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +15 -0
  112. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +27 -0
  113. data/spec/dragonfly/analysis/shared_analyser_spec.rb +51 -0
  114. data/spec/dragonfly/app_spec.rb +280 -0
  115. data/spec/dragonfly/config/r_magick_spec.rb +25 -0
  116. data/spec/dragonfly/configurable_spec.rb +220 -0
  117. data/spec/dragonfly/core_ext/string_spec.rb +17 -0
  118. data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
  119. data/spec/dragonfly/data_storage/data_store_spec.rb +76 -0
  120. data/spec/dragonfly/data_storage/file_data_store_spec.rb +169 -0
  121. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +38 -0
  122. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +94 -0
  123. data/spec/dragonfly/deprecation_spec.rb +20 -0
  124. data/spec/dragonfly/encoding/image_magick_encoder_spec.rb +41 -0
  125. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +37 -0
  126. data/spec/dragonfly/function_manager_spec.rb +154 -0
  127. data/spec/dragonfly/generation/hash_with_css_style_keys_spec.rb +24 -0
  128. data/spec/dragonfly/generation/image_magick_generator_spec.rb +12 -0
  129. data/spec/dragonfly/generation/r_magick_generator_spec.rb +24 -0
  130. data/spec/dragonfly/generation/shared_generator_spec.rb +91 -0
  131. data/spec/dragonfly/image_magick_utils_spec.rb +16 -0
  132. data/spec/dragonfly/job_builder_spec.rb +37 -0
  133. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  134. data/spec/dragonfly/job_endpoint_spec.rb +120 -0
  135. data/spec/dragonfly/job_spec.rb +773 -0
  136. data/spec/dragonfly/loggable_spec.rb +80 -0
  137. data/spec/dragonfly/middleware_spec.rb +68 -0
  138. data/spec/dragonfly/processing/image_magick_processor_spec.rb +29 -0
  139. data/spec/dragonfly/processing/r_magick_processor_spec.rb +26 -0
  140. data/spec/dragonfly/processing/shared_processing_spec.rb +215 -0
  141. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  142. data/spec/dragonfly/serializer_spec.rb +61 -0
  143. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  144. data/spec/dragonfly/simple_endpoint_spec.rb +89 -0
  145. data/spec/dragonfly/temp_object_spec.rb +352 -0
  146. data/spec/image_matchers.rb +47 -0
  147. data/spec/simple_matchers.rb +44 -0
  148. data/spec/spec_helper.rb +58 -0
  149. data/yard/handlers/configurable_attr_handler.rb +38 -0
  150. data/yard/setup.rb +15 -0
  151. data/yard/templates/default/fulldoc/html/css/common.css +107 -0
  152. data/yard/templates/default/layout/html/layout.erb +87 -0
  153. data/yard/templates/default/module/html/configuration_summary.erb +31 -0
  154. data/yard/templates/default/module/setup.rb +17 -0
  155. metadata +550 -0
@@ -0,0 +1,136 @@
1
+ Data Storage
2
+ ============
3
+
4
+ Each dragonfly app has a key-value datastore to store the content (originals only).
5
+
6
+ Lets say we have an app
7
+
8
+ app = Dragonfly[:my_app_name]
9
+
10
+ Then we can store data like so:
11
+
12
+ uid = app.store('SOME CONTENT') # Can pass in a String, File or Tempfile
13
+
14
+ We can also save metadata at the same time, and give it a name and format (if you pass in a File object the filename is used by default)
15
+
16
+ uid = app.store('SOME CONTENT',
17
+ :meta => {:time => Time.now},
18
+ :name => 'great_content.txt',
19
+ :format => :txt
20
+ )
21
+
22
+ We can get content with
23
+
24
+ content = app.fetch(uid)
25
+ content.data # "SOME CONTENT"
26
+
27
+ We can also get the extra saved attributes
28
+
29
+ content.meta # {:time => Sat Aug 14 12:04:13 +0100 2010}
30
+ content.name # 'great_content.txt'
31
+ content.format # :txt
32
+
33
+ We can destroy it with
34
+
35
+ app.destroy(uid)
36
+
37
+ You can create your own datastore, or use one of the provided ones as outlined below.
38
+
39
+ File datastore
40
+ --------------
41
+ The {Dragonfly::DataStorage::FileDataStore FileDataStore} stores data on the local filesystem.
42
+
43
+ It is used by default.
44
+
45
+ If for whatever reason you need to configure it again:
46
+
47
+ # shouldn't need this - it is the default
48
+ app.datastore = Dragonfly::DataStorage::FileDataStore.new
49
+
50
+ app.datastore.configure do |d|
51
+ d.root_path = '/my/custom/path' # defaults to /var/tmp/dragonfly
52
+ end
53
+
54
+
55
+ S3 datastore
56
+ ------------
57
+ To configure with the {Dragonfly::DataStorage::S3DataStore S3DataStore}:
58
+
59
+ app.datastore = Dragonfly::DataStorage::S3DataStore.new
60
+
61
+ app.datastore.configure do |d|
62
+ c.bucket_name = 'my_bucket'
63
+ c.access_key_id = 'salfjasd34u23'
64
+ c.secret_access_key = '8u2u3rhkhfo23...'
65
+ end
66
+
67
+ You can also pass these options to `S3DataStore.new` as an options hash.
68
+
69
+
70
+ Mongo datastore
71
+ ---------------
72
+ To configure with the {Dragonfly::DataStorage::MongoDataStore MongoDataStore}:
73
+
74
+ app.datastore = Dragonfly::DataStorage::MongoDataStore.new
75
+
76
+ It won't normally need configuring, but if you wish to:
77
+
78
+ app.datastore.configure do |d|
79
+ c.host = 'http://egg.heads:5000' # defaults to localhost
80
+ c.port = '27018' # defaults to mongo default (27017)
81
+ c.database = 'my_database' # defaults to 'dragonfly'
82
+ c.username = 'some_user' # only needed if mongo is running in auth mode
83
+ c.password = 'some_password' # only needed if mongo is running in auth mode
84
+ end
85
+
86
+ You can also pass these options to `MongoDataStore.new` as an options hash.
87
+
88
+ Custom datastore
89
+ ----------------
90
+ Data stores are key-value in nature, and need to implement 3 methods: `store`, `retrieve` and `destroy`.
91
+
92
+ class MyDataStore
93
+
94
+ def store(temp_object, opts={})
95
+ # ... use temp_object.data, temp_object.file, temp_object.path, etc. ...
96
+ # ... can also make use of temp_object.name, temp_object.format, temp_object.meta
97
+ # store and return the uid
98
+ 'return_some_unique_uid'
99
+ end
100
+
101
+ def retrieve(uid)
102
+ # return an array containing
103
+ [
104
+ content, # either a File, String or Tempfile
105
+ extra_data # Hash with optional keys :meta, :name, :format
106
+ ]
107
+ end
108
+
109
+ def destroy(uid)
110
+ # find the content and destroy
111
+ end
112
+
113
+ end
114
+
115
+ You can now configure the app to use your datastore:
116
+
117
+ Dragonfly[:my_app_name].datastore = MyDataStore.new
118
+
119
+ Notice that `store` takes a second `opts` argument.
120
+ Any options other than `meta`, `name` and `format` get passed through to here, so calling
121
+
122
+ uid = app.store('SOME CONTENT',
123
+ :name => 'great_content.txt',
124
+ :some_other => :option
125
+ )
126
+
127
+ will be split inside `store` like so:
128
+
129
+ def store(temp_object, opts={})
130
+ temp_object.data # "SOME CONTENT"
131
+ temp_object.name # 'great_content.txt'
132
+ opts # {:some_other => :option}
133
+ # ...
134
+ end
135
+
136
+ # ...
@@ -0,0 +1,96 @@
1
+ Encoding
2
+ ========
3
+
4
+ Changing the format of data, but not changing the data itself,
5
+ e.g. converting to gif format, comes under the banner of Encoding.
6
+
7
+ You can register as many encoders as you like.
8
+
9
+ Let's say we have a Dragonfly app
10
+
11
+ app = Dragonfly[:images]
12
+
13
+ and an image object (actually a {Dragonfly::Job Job} object)...
14
+
15
+ image = app.fetch('some/uid')
16
+
17
+ ...OR a Dragonfly model accessor...
18
+
19
+ image = @album.cover_image
20
+
21
+ We can encode it to any format registered with the encoder.
22
+
23
+ ImageMagickEncoder
24
+ ------------------
25
+ The {Dragonfly::Encoding::ImageMagickEncoder ImageMagickEncoder} is registered by default by
26
+ the {Dragonfly::Config::ImageMagick ImageMagick configuration} used by 'dragonfly/rails/images'.
27
+
28
+ If not already registered:
29
+
30
+ app.encoder.register(Dragonfly::Encoding::ImageMagickEncoder)
31
+
32
+ gives us:
33
+
34
+ image.encode(:jpg)
35
+ image.encode(:gif)
36
+ image.encode(:png)
37
+ image.encode(:tiff)
38
+
39
+ and various other formats (see {Dragonfly::Encoding::ImageMagickEncoder ImageMagickEncoder}).
40
+
41
+ You can also pass additional options to the imagemagick command line:
42
+
43
+ image.encode(:jpg, '-quality 10')
44
+
45
+ RMagickEncoder
46
+ --------------
47
+ The {Dragonfly::Encoding::RMagickEncoder RMagickEncoder} uses the {http://rmagick.rubyforge.org RMagick} library to do similar things to the
48
+ ImageMagickEncoder above.
49
+
50
+ You can tell it not to use the file system when registering it using
51
+
52
+ app.encoder.register(Dragonfly::Encoding::RMagickEncoder){|e| e.use_filesystem = false }
53
+
54
+ Lazy evaluation
55
+ ---------------
56
+
57
+ gif_image = image.encode(:gif)
58
+
59
+ doesn't actually do anything until you call something on the returned {Dragonfly::Job Job} object, like `url`, `data`, etc.
60
+
61
+ Bang method
62
+ -----------
63
+
64
+ image.encode!(:gif)
65
+
66
+ modifies the image object itself, rather than returning a new object.
67
+
68
+ Custom Encoders
69
+ ---------------
70
+
71
+ To register a custom encoder, for e.g. pdf format:
72
+
73
+ app.encoder.add do |temp_object, format|
74
+ throw :unable_to_handle unless format == :pdf
75
+ # use temp_object.data, temp_object.path, temp_object.file, etc.
76
+ SomeLibrary.convert_to_pdf(temp_object.data)
77
+ # return a String, File or Tempfile
78
+ end
79
+
80
+ pdf_image = image.encode(:pdf)
81
+
82
+ If `:unable_to_handle` is thrown, the next most recently registered encoder is used, and so on.
83
+
84
+ Alternatively you can create a class like the ImageMagick one above, which implements the method `encode`, and register this.
85
+
86
+ class MyEncoder
87
+
88
+ def encode(temp_object, format, *args)
89
+ SomeLib.encode(temp_object.data, format, *args)
90
+ end
91
+
92
+ end
93
+
94
+ app.encoder.register(MyEncoder)
95
+
96
+ pdf_image = image.encode(:pdf, :some => :args)
@@ -0,0 +1,121 @@
1
+ General Usage
2
+ =============
3
+
4
+ You can have multiple dragonfly apps, each with their own configuration.
5
+ Each app has a name, and is referred to by that name.
6
+
7
+ Dragonfly[:images] # ===> Creates an app called 'images'
8
+ Dragonfly[:images] # ===> Refers to the already created app 'images'
9
+
10
+ app = Dragonfly[:images]
11
+
12
+ Getting/generating content
13
+ --------------------------
14
+ Three methods can be used to get content:
15
+
16
+ app.fetch('some_uid') # Fetch from datastore (default filesystem)
17
+
18
+ app.fetch_file('~/path/to/file.png') # Fetch from a local file
19
+
20
+ app.generate(:plasma, 400, 300) # Generates using a method from the configured
21
+ # generator (in this case a plasma image)
22
+
23
+ These all return {Dragonfly::Job Job} objects. These objects are lazy - they don't do any fetching/generating until
24
+ some other method is called on them.
25
+
26
+ Using the content
27
+ -----------------
28
+ Once we have a {Dragonfly::Job Job} object:
29
+
30
+ image = app.fetch('some_uid')
31
+
32
+ We can get the data a number of ways...
33
+
34
+ image.data # => "\377???JFIF\000\..."
35
+ image.to_file('out.png') # writes to file 'out.png' and returns a readable file object
36
+ image.tempfile # => #<File:/var/folders/st/strHv74sH044JPabSiODz... a closed Tempfile object
37
+ image.file # => #<File:/var/folders/st/strHv74sH044JPabSiODz... a readable (open) File object
38
+ image.file do |f| # Yields an open file object, returns the return value of
39
+ data = f.read(256) # the block, and closes the file object
40
+ end
41
+ image.path # => '/var/folders/st/strHv74sH044JPabSiODz...' i.e. the path of the tempfile
42
+ image.size # => 134507 (size in bytes)
43
+
44
+ We can get its url...
45
+
46
+ image.url # => "/media/BAhbBlsHOgZmIg9hc..."
47
+
48
+ We can analyse it (see {file:Analysers} for more info) ...
49
+
50
+ image.width # => 280
51
+
52
+ We can process it (see {file:Processing} for more info) ...
53
+
54
+ new_image = image.process(:thumb, '40x30') # returns another 'Job' object
55
+
56
+ We can encode it (see {file:Encoding} for more info) ...
57
+
58
+ new_image = image.encode(:gif) # returns another 'Job' object
59
+
60
+ Chaining
61
+ --------
62
+ Because the methods
63
+
64
+ - `fetch`
65
+
66
+ - `fetch_file`
67
+
68
+ - `generate`
69
+
70
+ - `process`
71
+
72
+ - `encode`
73
+
74
+ all return {Dragonfly::Job Job} objects, we can chain them as much as we want...
75
+
76
+ image = app.fetch('some_uid').process(:greyscale).process(:thumb, '40x20#').encode(:gif)
77
+
78
+ ... and because they're lazy, we don't actually do any processing/encoding until either `apply` is called
79
+
80
+ image.apply # actually 'does' the processing and returns self
81
+
82
+ ... or a method is called like `data`, `to_file`, etc.
83
+
84
+ This means we can cheaply generate urls for processed data without doing any fetching or processing:
85
+
86
+ url = app.fetch('some_uid').process(:thumb, '40x20#').encode(:gif).url
87
+
88
+ and then visit that url in a browser to get the actual processed image.
89
+
90
+ Shortcuts
91
+ ---------
92
+ Commonly used processing/encoding steps can be shortened, so instead of
93
+
94
+ app.fetch('some_uid').process(:greyscale).process(:thumb, '40x20#').encode(:jpg)
95
+
96
+ we could use something like
97
+
98
+ app.fetch('some_uid').grey('40x20#')
99
+
100
+ This does exactly the same, returning a {Dragonfly::Job Job} object.
101
+
102
+ To define this shortcut:
103
+
104
+ app.configure do |c|
105
+ c.job :grey do |size|
106
+ process :greyscale
107
+ process :thumb, size
108
+ encode :jpg
109
+ end
110
+ # ...
111
+ end
112
+
113
+ The {Dragonfly::Config::ImageMagick ImageMagick} configuration comes with the pre-defined shortcuts:
114
+
115
+ image.thumb('40x30') # same as image.process(:thumb, '40x30')
116
+ image.jpg # same as image.encode(:jpg)
117
+ image.png # same as image.encode(:png)
118
+ image.gif # same as image.encode(:gif)
119
+ image.convert('-scale 30x30') # same as image.process(:convert, '-scale 30x30')
120
+
121
+ `thumb` and `convert` can optionally take a format (e.g. :gif) as the second argument.
@@ -0,0 +1,102 @@
1
+ Generators
2
+ ==========
3
+
4
+ Unlike processors and encoders, generators create content out of nothing, rather than modifying already existing content, for example text image generation.
5
+
6
+ You can register as many generators as you like.
7
+
8
+ Given a Dragonfly app
9
+
10
+ app = Dragonfly[:images]
11
+
12
+ we can get generated content using
13
+
14
+ image = app.generate(:some_method, :some => :args)
15
+
16
+ where `:some_method` is added by the configured generators.
17
+
18
+ ImageMagickGenerator
19
+ --------------------
20
+ The {Dragonfly::Generation::ImageMagickGenerator ImageMagickGenerator} is registered by default by the
21
+ {Dragonfly::Config::ImageMagick ImageMagick configuration} used by 'dragonfly/rails/images'.
22
+
23
+ If not already registered:
24
+
25
+ app.generator.register(Dragonfly::Generation::ImageMagickGenerator)
26
+
27
+ gives us these methods:
28
+
29
+ image = app.generate(:plasma, 600, 400, :gif) # generate a 600x400 plasma image
30
+ # last arg defaults to :png
31
+
32
+ image = app.generate(:text, "Hello there") # an image of the text "Hello there"
33
+
34
+ image = app.generate(:text, "Hello there",
35
+ :font_size => 30, # defaults to 12
36
+ :font_family => 'Monaco',
37
+ :stroke_color => '#ddd',
38
+ :color => 'red',
39
+ :font_style => 'italic',
40
+ :font_stretch => 'expanded',
41
+ :font_weight => 'bold',
42
+ :padding => '30 20 10',
43
+ :background_color => '#efefef', # defaults to transparent
44
+ :format => :gif # defaults to png
45
+ )
46
+
47
+ Note that the options are meant to resemble css as much as possible. You can also use, for example, `'font-family'` instead of `:font_family`.
48
+
49
+ You can use `padding-top`, `padding-left`, etc., as well as the standard css shortcuts for `padding` (it assumes unit is px).
50
+
51
+ An alternative for `:font_family` is `:font` (see {http://www.imagemagick.org/script/command-line-options.php#font}), which could be a complete filename.
52
+ Available fonts are those available on your system.
53
+
54
+ RMagickGenerator
55
+ ----------------
56
+ The {Dragonfly::Generation::RMagickGenerator RMagickGenerator} gives you `plasma` and `text` like the imagemagick generator above, using the
57
+ {http://rmagick.rubyforge.org RMagick} library.
58
+
59
+ You can tell it not to use the file system when registering it
60
+
61
+ app.generator.register(Dragonfly::Generation::RMagickGenerator){|g| g.use_filesystem = false }
62
+
63
+
64
+ Custom Generators
65
+ -----------------
66
+ To register a single custom generator:
67
+
68
+ app.generator.add :blank_image do |colour|
69
+ SomeLibrary.create_blank_image(colour) # return a String, File or Tempfile
70
+ end
71
+
72
+ app.generate(:blank_image, 'red') # => 'Job' object which we can get data, etc.
73
+
74
+
75
+ Or create a class like the ImageMagick one above, in which case all public methods will be counted as generator methods.
76
+
77
+ class RoundedCornerGenerator
78
+
79
+ def top_left_corner(opts={})
80
+ SomeLib.tlc(opts)
81
+ end
82
+
83
+ def bottom_right_corner(opts={})
84
+ tempfile = Tempfile.new('brc')
85
+ `some_command -c #{opts[:colour]} -o #{tempfile.path}`
86
+ tempfile
87
+ end
88
+
89
+ # ...
90
+
91
+ private
92
+
93
+ def my_helper_method
94
+ # do stuff
95
+ end
96
+
97
+ end
98
+
99
+ app.generator.register(RoundedCornerGenerator)
100
+
101
+ app.generate(:top_left_corner, :colour => 'green')
102
+ app.generate(:bottom_right_corner, :colour => 'mauve')