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.
- data/{.specopts → .rspec} +0 -1
- data/.yardopts +6 -2
- data/Gemfile +14 -13
- data/History.md +47 -9
- data/README.md +25 -5
- data/Rakefile +37 -79
- data/VERSION +1 -1
- data/dragonfly.gemspec +140 -89
- data/extra_docs/Analysers.md +8 -48
- data/extra_docs/Configuration.md +40 -25
- data/extra_docs/Couch.md +49 -0
- data/extra_docs/DataStorage.md +94 -24
- data/extra_docs/Encoding.md +6 -35
- data/extra_docs/ExampleUseCases.md +113 -0
- data/extra_docs/GeneralUsage.md +7 -23
- data/extra_docs/Generators.md +15 -49
- data/extra_docs/Heroku.md +7 -8
- data/extra_docs/ImageMagick.md +126 -0
- data/extra_docs/MimeTypes.md +3 -3
- data/extra_docs/Models.md +163 -0
- data/extra_docs/Mongo.md +1 -4
- data/extra_docs/Processing.md +7 -60
- data/extra_docs/Rails2.md +3 -1
- data/extra_docs/Rails3.md +2 -10
- data/extra_docs/ServingRemotely.md +83 -0
- data/extra_docs/Sinatra.md +3 -3
- data/extra_docs/URLs.md +60 -33
- data/features/rails_3.0.5.feature +8 -0
- data/features/steps/rails_steps.rb +7 -18
- data/features/support/env.rb +10 -37
- data/features/support/setup.rb +32 -0
- data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
- data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -0
- data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
- data/fixtures/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
- data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
- data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
- data/irbrc.rb +2 -1
- data/lib/dragonfly.rb +7 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
- data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
- data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
- data/lib/dragonfly/analyser.rb +0 -1
- data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
- data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
- data/lib/dragonfly/app.rb +64 -55
- data/lib/dragonfly/config/heroku.rb +1 -1
- data/lib/dragonfly/config/image_magick.rb +2 -37
- data/lib/dragonfly/config/rails.rb +5 -2
- data/lib/dragonfly/configurable.rb +115 -35
- data/lib/dragonfly/core_ext/object.rb +1 -1
- data/lib/dragonfly/core_ext/string.rb +1 -1
- data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
- data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
- data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
- data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
- data/lib/dragonfly/function_manager.rb +4 -2
- data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
- data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
- data/lib/dragonfly/image_magick/analyser.rb +51 -0
- data/lib/dragonfly/image_magick/config.rb +44 -0
- data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
- data/lib/dragonfly/image_magick/generator.rb +145 -0
- data/lib/dragonfly/image_magick/processor.rb +104 -0
- data/lib/dragonfly/image_magick/utils.rb +72 -0
- data/lib/dragonfly/image_magick_utils.rb +2 -79
- data/lib/dragonfly/job.rb +152 -90
- data/lib/dragonfly/middleware.rb +5 -19
- data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
- data/lib/dragonfly/rails/images.rb +15 -10
- data/lib/dragonfly/response.rb +26 -12
- data/lib/dragonfly/serializer.rb +1 -4
- data/lib/dragonfly/server.rb +103 -0
- data/lib/dragonfly/temp_object.rb +56 -101
- data/lib/dragonfly/url_mapper.rb +78 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
- data/spec/dragonfly/analyser_spec.rb +1 -1
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
- data/spec/dragonfly/app_spec.rb +35 -180
- data/spec/dragonfly/configurable_spec.rb +259 -18
- data/spec/dragonfly/core_ext/string_spec.rb +2 -2
- data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
- data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
- data/spec/dragonfly/function_manager_spec.rb +2 -2
- data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
- data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
- data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
- data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
- data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
- data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
- data/spec/dragonfly/job_builder_spec.rb +1 -1
- data/spec/dragonfly/job_definitions_spec.rb +1 -1
- data/spec/dragonfly/job_endpoint_spec.rb +26 -3
- data/spec/dragonfly/job_spec.rb +426 -208
- data/spec/dragonfly/loggable_spec.rb +2 -2
- data/spec/dragonfly/middleware_spec.rb +5 -26
- data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
- data/spec/dragonfly/serializer_spec.rb +1 -14
- data/spec/dragonfly/server_spec.rb +261 -0
- data/spec/dragonfly/simple_cache_spec.rb +1 -1
- data/spec/dragonfly/temp_object_spec.rb +84 -130
- data/spec/dragonfly/url_mapper_spec.rb +130 -0
- data/spec/functional/deprecations_spec.rb +51 -0
- data/spec/functional/image_magick_app_spec.rb +27 -0
- data/spec/functional/model_urls_spec.rb +85 -0
- data/spec/functional/remote_on_the_fly_spec.rb +51 -0
- data/spec/functional/to_response_spec.rb +31 -0
- data/spec/spec_helper.rb +12 -22
- data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
- data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
- data/spec/support/simple_matchers.rb +53 -0
- data/yard/handlers/configurable_attr_handler.rb +2 -2
- data/yard/templates/default/fulldoc/html/css/common.css +12 -10
- data/yard/templates/default/layout/html/layout.erb +6 -0
- metadata +267 -308
- data/Gemfile.rails.2.3.5 +0 -20
- data/features/3.0.3.feature +0 -8
- data/features/rails_2.3.5.feature +0 -7
- data/fixtures/files/app/models/album.rb +0 -3
- data/fixtures/files/app/views/albums/new.html.erb +0 -4
- data/fixtures/files/features/manage_album_images.feature +0 -12
- data/fixtures/rails_2.3.5/template.rb +0 -10
- data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
- data/lib/dragonfly/config/r_magick.rb +0 -46
- data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
- data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
- data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
- data/lib/dragonfly/r_magick_utils.rb +0 -48
- data/lib/dragonfly/simple_endpoint.rb +0 -76
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
- data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
- data/spec/dragonfly/config/r_magick_spec.rb +0 -29
- data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
- data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
- data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
- data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
- data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
- data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
- data/spec/simple_matchers.rb +0 -44
data/Gemfile.rails.2.3.5
DELETED
@@ -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
|
data/features/3.0.3.feature
DELETED
@@ -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,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
|