magickly 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -5
- data/Gemfile.lock +12 -10
- data/HISTORY.md +24 -0
- data/README.md +70 -30
- data/VERSION +1 -1
- data/lib/dragonfly/app.rb +8 -0
- data/lib/dragonfly/data_storage/remote_data_store.rb +1 -1
- data/lib/images/lomo_mask.png +0 -0
- data/lib/magickly.rb +5 -2
- data/lib/magickly/app.rb +37 -5
- data/lib/shortcuts.rb +75 -4
- data/lib/views/analyzers.haml +3 -0
- data/lib/views/index.haml +1 -1
- data/magickly.gemspec +15 -9
- data/spec/requests/magickly_app_spec.rb +45 -8
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/shortcut_spec.rb +60 -0
- metadata +117 -42
data/Gemfile
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
|
-
# gem 'activesupport', '>= 2.3.5'
|
5
2
|
|
6
3
|
gem 'sinatra', '~> 1.2.1', :require => 'sinatra/base'
|
7
4
|
gem 'dragonfly', '~> 0.9.1'
|
@@ -10,9 +7,8 @@ gem 'addressable', '~> 2.2', :require => 'addressable/uri'
|
|
10
7
|
gem 'haml', '~> 3.0'
|
11
8
|
gem 'httparty', '~> 0.7.3'
|
12
9
|
gem 'activesupport', '>= 2.0.0', :require => false
|
10
|
+
gem 'json', '~> 1.5'
|
13
11
|
|
14
|
-
# Add dependencies to develop your gem here.
|
15
|
-
# Include everything needed to run rake, tests, features, etc.
|
16
12
|
group :development do
|
17
13
|
gem 'jeweler', '~> 1.5'
|
18
14
|
gem 'rcov', '>= 0'
|
data/Gemfile.lock
CHANGED
@@ -1,39 +1,40 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (3.0.
|
4
|
+
activesupport (3.0.9)
|
5
5
|
addressable (2.2.6)
|
6
6
|
crack (0.1.8)
|
7
7
|
diff-lcs (1.1.2)
|
8
|
-
dragonfly (0.9.
|
8
|
+
dragonfly (0.9.4)
|
9
9
|
rack
|
10
10
|
git (1.2.5)
|
11
|
-
haml (3.1.
|
12
|
-
httparty (0.7.
|
11
|
+
haml (3.1.2)
|
12
|
+
httparty (0.7.8)
|
13
13
|
crack (= 0.1.8)
|
14
14
|
imagesize (0.1.1)
|
15
|
-
jeweler (1.6.
|
16
|
-
bundler (~> 1.0
|
15
|
+
jeweler (1.6.2)
|
16
|
+
bundler (~> 1.0)
|
17
17
|
git (>= 1.2.5)
|
18
18
|
rake
|
19
|
-
|
19
|
+
json (1.5.3)
|
20
|
+
newrelic_rpm (3.1.0)
|
20
21
|
rack (1.3.0)
|
21
22
|
rack-test (0.6.0)
|
22
23
|
rack (>= 1.0)
|
23
|
-
rake (0.9.
|
24
|
+
rake (0.9.2)
|
24
25
|
rcov (0.9.9)
|
25
26
|
rspec (2.6.0)
|
26
27
|
rspec-core (~> 2.6.0)
|
27
28
|
rspec-expectations (~> 2.6.0)
|
28
29
|
rspec-mocks (~> 2.6.0)
|
29
|
-
rspec-core (2.6.
|
30
|
+
rspec-core (2.6.4)
|
30
31
|
rspec-expectations (2.6.0)
|
31
32
|
diff-lcs (~> 1.1.2)
|
32
33
|
rspec-mocks (2.6.0)
|
33
34
|
sinatra (1.2.6)
|
34
35
|
rack (~> 1.1)
|
35
36
|
tilt (< 2.0, >= 1.2.2)
|
36
|
-
tilt (1.3.
|
37
|
+
tilt (1.3.2)
|
37
38
|
webmock (1.6.4)
|
38
39
|
addressable (> 2.2.5, ~> 2.2)
|
39
40
|
crack (>= 0.1.7)
|
@@ -49,6 +50,7 @@ DEPENDENCIES
|
|
49
50
|
httparty (~> 0.7.3)
|
50
51
|
imagesize (~> 0.1)
|
51
52
|
jeweler (~> 1.5)
|
53
|
+
json (~> 1.5)
|
52
54
|
newrelic_rpm
|
53
55
|
rack-test
|
54
56
|
rcov
|
data/HISTORY.md
CHANGED
@@ -1,12 +1,32 @@
|
|
1
1
|
This gem respects [semantic versioning](http://semver.org/).
|
2
2
|
|
3
|
+
# 1.2.0 (6/28/11)
|
4
|
+
|
5
|
+
[commits](https://github.com/afeld/magickly/compare/v1.1.3...v1.2.0)
|
6
|
+
|
7
|
+
* add /analyze and /analyze/:analyzer endpoints
|
8
|
+
* fix for negative values for brightness_contrast
|
9
|
+
* validation & specs for existing shortcuts
|
10
|
+
* added shortcuts:
|
11
|
+
* color_palette (analyzer)
|
12
|
+
* cross_process
|
13
|
+
* glow
|
14
|
+
* halftone
|
15
|
+
* lomo
|
16
|
+
* saturation
|
17
|
+
* two_color
|
18
|
+
|
3
19
|
# 1.1.3 (5/26/11)
|
4
20
|
|
21
|
+
[commits](https://github.com/afeld/magickly/compare/v1.1.2...v1.1.3)
|
22
|
+
|
5
23
|
* make tilt-shift faster
|
6
24
|
* add brightness_contrast shortcut
|
7
25
|
|
8
26
|
# 1.1.2 (5/16/11)
|
9
27
|
|
28
|
+
[commits](https://github.com/afeld/magickly/compare/v1.1.1...v1.1.2)
|
29
|
+
|
10
30
|
* remove rack-cache - this is not the responsibility of the gem
|
11
31
|
* use NewRelic, if configured
|
12
32
|
* ignore params that do not correspond to jobs or processor methods
|
@@ -15,11 +35,15 @@ This gem respects [semantic versioning](http://semver.org/).
|
|
15
35
|
|
16
36
|
# 1.1.1 (4/28/11)
|
17
37
|
|
38
|
+
[commits](https://github.com/afeld/magickly/compare/v1.1.0...v1.1.1)
|
39
|
+
|
18
40
|
* cross-compatibility fix for Ruby 1.8/1.9 regarding the checking of available methods from the Processor
|
19
41
|
* Addressable now required properly when included as a gem
|
20
42
|
|
21
43
|
# 1.1.0 (4/26/11)
|
22
44
|
|
45
|
+
[commits](https://github.com/afeld/magickly/compare/v1.0.0...v1.1.0)
|
46
|
+
|
23
47
|
* make underlying Dragonfly application accessible for external configuration
|
24
48
|
* added some example Dragonfly shortcuts
|
25
49
|
* major refactoring: namespacing inside of Magickly module (should be entirely backwards compatible)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# magickly
|
1
|
+
# magickly [![Build Status](http://travis-ci.org/afeld/magickly.png)](http://travis-ci.org/afeld/magickly)
|
2
2
|
|
3
3
|
A service for image manipulation - built as a simple wrapper of Imagemagick which handles caching, c/o the [Dragonfly](http://markevans.github.com/dragonfly/) gem.
|
4
4
|
|
@@ -8,7 +8,35 @@ If no query params are provided, a simple sandbox page is displayed. Try it her
|
|
8
8
|
|
9
9
|
[magickly.heroku.com](http://magickly.heroku.com)
|
10
10
|
|
11
|
-
##
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Requires Imagemagick >= v6.2.4.
|
14
|
+
|
15
|
+
$ gem install magickly
|
16
|
+
|
17
|
+
## Running the App
|
18
|
+
|
19
|
+
A few options:
|
20
|
+
|
21
|
+
### A. Run the app directly
|
22
|
+
|
23
|
+
$ magickly
|
24
|
+
|
25
|
+
The app can be accessed at [http://localhost:4567](http://localhost:4567)
|
26
|
+
|
27
|
+
### B. Use as an endpoint in another Rack app
|
28
|
+
|
29
|
+
As an example, to have magickly accessible at `/magickly` in a Rails app:
|
30
|
+
|
31
|
+
# Gemfile
|
32
|
+
gem 'magickly', '~> 1.1'
|
33
|
+
|
34
|
+
# config/routes.rb
|
35
|
+
match '/magickly', :to => Magickly::App, :anchor => false
|
36
|
+
|
37
|
+
For more info, see [Rails Routing from the Outside In](http://guides.rubyonrails.org/routing.html#routing-to-rack-applications) or Michael Raidel's [Mount Rails apps in Rails 3](http://inductor.induktiv.at/blog/2010/05/23/mount-rack-apps-in-rails-3/).
|
38
|
+
|
39
|
+
## Processing Parameters
|
12
40
|
|
13
41
|
*See the [Dragonfly documentation](http://markevans.github.com/dragonfly/file.ImageMagick.html) for more details about the permitted* `geometry` *values.*
|
14
42
|
|
@@ -18,7 +46,7 @@ The URL of the original image.
|
|
18
46
|
|
19
47
|
### brightness_contrast=*brightness* x *contrast*
|
20
48
|
|
21
|
-
*brightness* and *contrast* are percentage change, between -100 and 100. For example, to increase contrast by 20% but leave brightness
|
49
|
+
*brightness* and *contrast* are percentage change, between -100 and 100. For example, to increase contrast by 20% but leave brightness unchanged, use `brightness_contrast=0x20`.
|
22
50
|
|
23
51
|
![tanned imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&brightness_contrast=-10x50)
|
24
52
|
|
@@ -36,12 +64,28 @@ The URL of the original image.
|
|
36
64
|
|
37
65
|
[http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&flop=true](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&flop=true)
|
38
66
|
|
67
|
+
### glow=*amount*,*softness*
|
68
|
+
|
69
|
+
where `amount` is a float >= 1.0, and `softness` is an int >= 0.
|
70
|
+
|
71
|
+
![glowing imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&glow=1.2,20)
|
72
|
+
|
73
|
+
[http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&glow=1.2,20](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&glow=1.2,20)
|
74
|
+
|
39
75
|
### greyscale=true
|
40
76
|
|
41
77
|
![flopped imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&greyscale=true)
|
42
78
|
|
43
79
|
[http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&greyscale=true](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&greyscale=true)
|
44
80
|
|
81
|
+
### halftone=*threshold*
|
82
|
+
|
83
|
+
where *threshold* is a value between 0 and 100.
|
84
|
+
|
85
|
+
![halftone imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&halftone=60)
|
86
|
+
|
87
|
+
[http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&halftone=60](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&halftone=60)
|
88
|
+
|
45
89
|
### resize=*geometry*
|
46
90
|
|
47
91
|
![resized imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&resize=100x100)
|
@@ -54,6 +98,14 @@ The URL of the original image.
|
|
54
98
|
|
55
99
|
[http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&rotate=45](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&rotate=45)
|
56
100
|
|
101
|
+
### saturation=*percentage*
|
102
|
+
|
103
|
+
*percentage* is the percentage of variation: a positive integer. 100 means no change. For example, to increase saturation by 50%, use `saturation=150`.
|
104
|
+
|
105
|
+
![saturated imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&saturation=150)
|
106
|
+
|
107
|
+
[http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&saturation=150](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&saturation=150)
|
108
|
+
|
57
109
|
### tilt_shift=true
|
58
110
|
|
59
111
|
![tilt-shifted imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&tilt_shift=true)
|
@@ -68,9 +120,23 @@ The URL of the original image.
|
|
68
120
|
|
69
121
|
(note: the `%23` in the geometry string above is an encoded '`#`', which tells Dragonfly to fill the dimensions and crop)
|
70
122
|
|
123
|
+
### two_color=true
|
124
|
+
|
125
|
+
![two color imagemagick logo](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&two_color=true)
|
126
|
+
|
127
|
+
[http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&two_color=true](http://magickly.heroku.com/?src=http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Imagemagick-logo.png/200px-Imagemagick-logo.png&two_color=true)
|
128
|
+
|
129
|
+
## Analyzers
|
130
|
+
|
131
|
+
Magickly v1.2.0 introduces the ability to retrieve image properties via a REST API. For example, to retrieve the number of colors in the photo, visit:
|
132
|
+
|
133
|
+
[magickly.heroku.com/analyze/number_of_colors?src=http://upload.wikimedia.org/wikipedia/commons/0/0d/Imagemagick-logo.png](http://magickly.heroku.com/analyze/number_of_colors?src=http://upload.wikimedia.org/wikipedia/commons/0/0d/Imagemagick-logo.png)
|
134
|
+
|
135
|
+
To get the list of available analyzers, visit [magickly.heroku.com/analyze](http://magickly.heroku.com/analyze)
|
136
|
+
|
71
137
|
## Customization
|
72
138
|
|
73
|
-
In addition to the available listed above, custom "shortcuts" can be created to perform arbitrary imagemagick operations. For example, to create a shortcut called `resize_with_blur`:
|
139
|
+
In addition to the available parameters listed above, custom "shortcuts" can be created to perform arbitrary imagemagick operations. For example, to create a shortcut called `resize_with_blur`:
|
74
140
|
|
75
141
|
# somewhere in your app configuration, i.e. config/initializers/magickly.rb for a Rails 3 app
|
76
142
|
Magickly.dragonfly.configure do |c|
|
@@ -83,32 +149,6 @@ which can then be used with the query string `?src=...&resize_with_blur=200x`.
|
|
83
149
|
|
84
150
|
See the [Dragonfly documentation](http://markevans.github.com/dragonfly/file.GeneralUsage.html#Shortcuts) for more info on "shortcuts", and the [shortcuts.rb](https://github.com/afeld/magickly/blob/master/lib/shortcuts.rb) file for examples.
|
85
151
|
|
86
|
-
## Installation
|
87
|
-
|
88
|
-
$ gem install magickly
|
89
|
-
|
90
|
-
## Running the App
|
91
|
-
|
92
|
-
A few options:
|
93
|
-
|
94
|
-
### A. Run the app directly
|
95
|
-
|
96
|
-
$ magickly
|
97
|
-
|
98
|
-
The app can be accessed at [http://localhost:4567](http://localhost:4567)
|
99
|
-
|
100
|
-
### B. Use as an endpoint in another Rack app
|
101
|
-
|
102
|
-
As an example, to have magickly accessible at `/magickly` in a Rails app:
|
103
|
-
|
104
|
-
# Gemfile
|
105
|
-
gem 'magickly', '~> 1.1'
|
106
|
-
|
107
|
-
# config/routes.rb
|
108
|
-
match '/magickly', :to => Magickly::App, :anchor => false
|
109
|
-
|
110
|
-
For more info, see [Rails Routing from the Outside In](http://guides.rubyonrails.org/routing.html#routing-to-rack-applications) or Michael Raidel's [Mount Rails apps in Rails 3](http://inductor.induktiv.at/blog/2010/05/23/mount-rack-apps-in-rails-3/).
|
111
|
-
|
112
152
|
## Contributing to magickly
|
113
153
|
|
114
154
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
@@ -14,7 +14,7 @@ module Dragonfly
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def retrieve(uid)
|
17
|
-
response = HTTParty.get uid, :headers => {'cookie' => cookie_str || ''}
|
17
|
+
response = HTTParty.get uid, :headers => {'cookie' => cookie_str || ''}, :timeout => 3
|
18
18
|
unless response.ok?
|
19
19
|
#raise Forbidden if response.code == 403
|
20
20
|
raise DataNotFound
|
Binary file
|
data/lib/magickly.rb
CHANGED
@@ -4,15 +4,18 @@ require 'active_support/ordered_hash'
|
|
4
4
|
require 'sinatra/base'
|
5
5
|
require 'addressable/uri'
|
6
6
|
require 'dragonfly'
|
7
|
-
|
7
|
+
Dir["#{File.dirname(__FILE__)}/dragonfly/**/*.rb"].each {|file| require file }
|
8
8
|
Dir["#{File.dirname(__FILE__)}/magickly/*.rb"].each {|file| require file }
|
9
9
|
|
10
10
|
|
11
11
|
module Magickly
|
12
|
-
|
12
|
+
DEFAULT_PALETTE_COLOR_COUNT = 5
|
13
|
+
|
14
|
+
@dragonfly = Dragonfly[:magickly].configure_with(:imagemagick)
|
13
15
|
@dragonfly.configure do |c|
|
14
16
|
c.datastore = Dragonfly::DataStorage::RemoteDataStore.new
|
15
17
|
c.log = Logger.new($stdout)
|
18
|
+
c.log_commands = true
|
16
19
|
end
|
17
20
|
|
18
21
|
class << self
|
data/lib/magickly/app.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Magickly
|
2
2
|
class App < Sinatra::Base
|
3
3
|
RESERVED_PARAMS = ['src']
|
4
|
+
DEMO_IMAGE = 'http://upload.wikimedia.org/wikipedia/commons/0/0d/Imagemagick-logo.png'
|
4
5
|
|
5
6
|
enable :logging
|
6
7
|
set :root, File.join(File.dirname(__FILE__), '..')
|
@@ -29,21 +30,52 @@ module Magickly
|
|
29
30
|
|
30
31
|
if src
|
31
32
|
# process image
|
32
|
-
|
33
|
-
|
34
|
-
uri.site ||= Addressable::URI.parse(request.url).site
|
35
|
-
|
36
|
-
image = Magickly.process_src(uri.to_s, @options)
|
33
|
+
url = uri_to_url(src)
|
34
|
+
image = Magickly.process_src(url, @options)
|
37
35
|
image.to_response(env)
|
38
36
|
else
|
39
37
|
# display demo page
|
40
38
|
|
41
39
|
# get combined list of jobs and processor methods
|
42
40
|
@methods = ( Magickly.dragonfly.job_methods | Magickly.dragonfly.processor_methods )
|
41
|
+
@methods.sort!{|m1, m2| m1.to_s <=> m2.to_s }
|
43
42
|
haml :index
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
46
|
+
get '/analyze' do
|
47
|
+
@analyzers = Magickly.dragonfly.analyser_methods
|
48
|
+
@analyzers.sort!{|m1, m2| m1.to_s <=> m2.to_s }
|
49
|
+
haml :analyzers
|
50
|
+
end
|
51
|
+
|
52
|
+
get '/analyze/:name' do |method|
|
53
|
+
src = params[:src]
|
54
|
+
if src
|
55
|
+
url = uri_to_url(src)
|
56
|
+
image = Magickly.process_src(url, @options)
|
57
|
+
|
58
|
+
begin
|
59
|
+
output = image.send(method.to_sym)
|
60
|
+
rescue NoMethodError
|
61
|
+
method = method.to_s + '?'
|
62
|
+
output = image.send(method.to_sym)
|
63
|
+
end
|
64
|
+
|
65
|
+
output.is_a?(String) ? output : output.to_json
|
66
|
+
else
|
67
|
+
status 400
|
68
|
+
"Please provide an image URL with the src parameter."
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def uri_to_url(uri)
|
74
|
+
url = Addressable::URI.parse(uri)
|
75
|
+
url.site ||= Addressable::URI.parse(request.url).site
|
76
|
+
url.to_s
|
77
|
+
end
|
78
|
+
|
47
79
|
# start the server if ruby file executed directly
|
48
80
|
run! if __FILE__ == $0
|
49
81
|
end
|
data/lib/shortcuts.rb
CHANGED
@@ -1,20 +1,91 @@
|
|
1
1
|
Magickly.dragonfly.configure do |c|
|
2
2
|
c.job :brightness_contrast do |val|
|
3
|
+
raise ArgumentError, "argument must be of the format '<int>[%]x<int>[%]'" unless val =~ /^-?\d+%?(x-?\d+%?)?$/
|
3
4
|
process :convert, "-brightness-contrast #{val}"
|
4
5
|
end
|
5
6
|
|
7
|
+
c.job :saturation do |percentage|
|
8
|
+
raise ArgumentError, "percentage must be a positive integer" unless percentage =~ /^\d+$/
|
9
|
+
process :convert, "-modulate 100,#{percentage}"
|
10
|
+
end
|
11
|
+
|
6
12
|
c.job :resize_with_blur do |size|
|
7
13
|
process :convert, "-filter Gaussian -resize #{size}"
|
8
14
|
end
|
9
15
|
|
10
16
|
c.job :tilt_shift do |coefficients|
|
11
|
-
if coefficients == 'true'
|
12
|
-
|
13
|
-
coefficients = '4,-4,1'
|
14
|
-
end
|
17
|
+
coefficients = '4,-4,1' if coefficients == 'true'
|
18
|
+
raise ArgumentError, "coefficients must be of the format '<decimal>,<decimal>,<decimal>'" unless coefficients =~ /^(-?\d+(\.\d+)?,){2}-?\d+(\.\d+)?$/
|
15
19
|
|
16
20
|
# note: can be made faster by decreasing sigma passed to option:compose:args
|
17
21
|
action = "\\( +clone -sparse-color Barycentric '0,0 black 0,%h white' -function polynomial #{coefficients} \\) -compose Blur -set option:compose:args 8 -composite"
|
18
22
|
process :convert, action
|
19
23
|
end
|
24
|
+
|
25
|
+
# thanks to http://www.melissaevans.com/tutorials/pop-art-inspired-by-lichtenstein
|
26
|
+
c.job :halftone do |threshold|
|
27
|
+
threshold = 50 if threshold == 'true'
|
28
|
+
process :convert, "-white-threshold #{threshold.to_i}% -gaussian-blur 2 -ordered-dither 8x1"
|
29
|
+
end
|
30
|
+
|
31
|
+
# thanks to http://www.photoshopsupport.com/tutorials/or/cross-processing.html
|
32
|
+
c.job :cross_process do
|
33
|
+
process :convert, "-channel Red -sigmoidal-contrast 6,50% -channel Blue -level 25%\\! -channel Green -sigmoidal-contrast 5,45% \\( +clone +matte -fill yellow -colorize 4% \\) -compose overlay -composite"
|
34
|
+
end
|
35
|
+
|
36
|
+
## thanks to https://github.com/soveran/lomo
|
37
|
+
c.job :lomo do |modulate_params|
|
38
|
+
if modulate_params == 'true'
|
39
|
+
modulate_params = '100,150'
|
40
|
+
elsif modulate_params =~ /^\d+,\d+$/
|
41
|
+
# valid params
|
42
|
+
else
|
43
|
+
raise ArgumentError, "modulate_params must be of the format '<int>,<int>'"
|
44
|
+
end
|
45
|
+
|
46
|
+
lomo_mask = File.join(File.dirname(__FILE__), 'images', 'lomo_mask.png')
|
47
|
+
process :convert, "\\( +clone -unsharp 1 -contrast -contrast -modulate #{modulate_params} \\( #{lomo_mask} -resize #{@job.width}x#{@job.height}\\! \\) -compose overlay -composite \\) -compose multiply -composite"
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
## thanks to Fred Weinhaus (http://www.fmwconcepts.com/imagemagick) for the following: ##
|
52
|
+
|
53
|
+
c.job :glow do |args|
|
54
|
+
if args == 'true'
|
55
|
+
amount = 1.2
|
56
|
+
softening = 20
|
57
|
+
elsif args =~ /^(\d+\.\d+?),(\d+)$/ && $1.to_f >= 1.0 && $2.to_i >= 0
|
58
|
+
amount = $1
|
59
|
+
softening = $2
|
60
|
+
else
|
61
|
+
raise ArgumentError, "args must be of the form <amount(float)>,<softening(int)>"
|
62
|
+
end
|
63
|
+
|
64
|
+
process :convert, "\\( +clone -evaluate multiply #{amount} -blur 0x#{softening} \\) -compose plus -composite"
|
65
|
+
end
|
66
|
+
|
67
|
+
c.job :two_color do
|
68
|
+
process :convert, "-background black -flatten +matte +dither -colors 2 -colorspace gray -contrast-stretch 0"
|
69
|
+
end
|
70
|
+
|
71
|
+
#########################################################################################
|
72
|
+
|
73
|
+
|
74
|
+
c.job :color_palette_swatch do |count|
|
75
|
+
count = Magickly::DEFAULT_PALETTE_COLOR_COUNT if count == 'true'
|
76
|
+
|
77
|
+
process :convert, "-resize 600x600 -colors #{count} -unique-colors -scale 10000%"
|
78
|
+
encode :gif
|
79
|
+
end
|
80
|
+
|
81
|
+
c.analyser.add :color_palette do |temp_object, num_colors|
|
82
|
+
num_colors = num_colors.blank? ? Magickly::DEFAULT_PALETTE_COLOR_COUNT : num_colors.to_i
|
83
|
+
output = `convert #{temp_object.path} -resize 600x600 -colors #{num_colors} -format %c -depth 8 histogram:info:-`
|
84
|
+
|
85
|
+
palette = []
|
86
|
+
output.scan(/\s+(\d+):[^\n]+#([0-9A-Fa-f]{6})/) do |count, hex|
|
87
|
+
palette << { :count => count.to_i, :hex => hex }
|
88
|
+
end
|
89
|
+
palette
|
90
|
+
end
|
20
91
|
end
|
data/lib/views/index.haml
CHANGED
@@ -40,7 +40,7 @@
|
|
40
40
|
%br
|
41
41
|
%br
|
42
42
|
%label Image URL:
|
43
|
-
%input#src-img{:size => 80, :value =>
|
43
|
+
%input#src-img{:size => 80, :value => Magickly::App::DEMO_IMAGE}
|
44
44
|
%br
|
45
45
|
%label Params:
|
46
46
|
%input#params{:size => 80, :value => "resize=200x"}
|
data/magickly.gemspec
CHANGED
@@ -5,15 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{magickly}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{2011-
|
13
|
-
s.default_executable = %q{magickly}
|
11
|
+
s.authors = [%q{Aidan Feldman}]
|
12
|
+
s.date = %q{2011-06-29}
|
14
13
|
s.description = %q{A service for image manipulation - built as an extensible wrapper of Imagemagick which handles caching, c/o the Dragonfly gem.}
|
15
14
|
s.email = %q{aidan.feldman@gmail.com}
|
16
|
-
s.executables = [
|
15
|
+
s.executables = [%q{magickly}]
|
17
16
|
s.extra_rdoc_files = [
|
18
17
|
"LICENSE.txt",
|
19
18
|
"README.md"
|
@@ -31,23 +30,27 @@ Gem::Specification.new do |s|
|
|
31
30
|
"VERSION",
|
32
31
|
"bin/magickly",
|
33
32
|
"config.ru",
|
33
|
+
"lib/dragonfly/app.rb",
|
34
34
|
"lib/dragonfly/data_storage/remote_data_store.rb",
|
35
|
+
"lib/images/lomo_mask.png",
|
35
36
|
"lib/magickly.rb",
|
36
37
|
"lib/magickly/app.rb",
|
37
38
|
"lib/public/imagemagick.png",
|
38
39
|
"lib/shortcuts.rb",
|
40
|
+
"lib/views/analyzers.haml",
|
39
41
|
"lib/views/index.haml",
|
40
42
|
"magickly.gemspec",
|
41
43
|
"spec/requests/magickly_app_spec.rb",
|
42
44
|
"spec/spec_helper.rb",
|
43
45
|
"spec/support/imagemagick.png",
|
44
46
|
"spec/unit/magickly_spec.rb",
|
45
|
-
"spec/unit/remote_data_store_spec.rb"
|
47
|
+
"spec/unit/remote_data_store_spec.rb",
|
48
|
+
"spec/unit/shortcut_spec.rb"
|
46
49
|
]
|
47
50
|
s.homepage = %q{http://github.com/afeld/magickly}
|
48
|
-
s.licenses = [
|
49
|
-
s.require_paths = [
|
50
|
-
s.rubygems_version = %q{1.
|
51
|
+
s.licenses = [%q{MIT}]
|
52
|
+
s.require_paths = [%q{lib}]
|
53
|
+
s.rubygems_version = %q{1.8.5}
|
51
54
|
s.summary = %q{image manipulation as a (plugin-able) service}
|
52
55
|
|
53
56
|
if s.respond_to? :specification_version then
|
@@ -60,6 +63,7 @@ Gem::Specification.new do |s|
|
|
60
63
|
s.add_runtime_dependency(%q<haml>, ["~> 3.0"])
|
61
64
|
s.add_runtime_dependency(%q<httparty>, ["~> 0.7.3"])
|
62
65
|
s.add_runtime_dependency(%q<activesupport>, [">= 2.0.0"])
|
66
|
+
s.add_runtime_dependency(%q<json>, ["~> 1.5"])
|
63
67
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5"])
|
64
68
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
65
69
|
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
@@ -73,6 +77,7 @@ Gem::Specification.new do |s|
|
|
73
77
|
s.add_dependency(%q<haml>, ["~> 3.0"])
|
74
78
|
s.add_dependency(%q<httparty>, ["~> 0.7.3"])
|
75
79
|
s.add_dependency(%q<activesupport>, [">= 2.0.0"])
|
80
|
+
s.add_dependency(%q<json>, ["~> 1.5"])
|
76
81
|
s.add_dependency(%q<jeweler>, ["~> 1.5"])
|
77
82
|
s.add_dependency(%q<rcov>, [">= 0"])
|
78
83
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
@@ -87,6 +92,7 @@ Gem::Specification.new do |s|
|
|
87
92
|
s.add_dependency(%q<haml>, ["~> 3.0"])
|
88
93
|
s.add_dependency(%q<httparty>, ["~> 0.7.3"])
|
89
94
|
s.add_dependency(%q<activesupport>, [">= 2.0.0"])
|
95
|
+
s.add_dependency(%q<json>, ["~> 1.5"])
|
90
96
|
s.add_dependency(%q<jeweler>, ["~> 1.5"])
|
91
97
|
s.add_dependency(%q<rcov>, [">= 0"])
|
92
98
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
describe Magickly::App do
|
4
5
|
include Rack::Test::Methods
|
@@ -7,14 +8,14 @@ describe Magickly::App do
|
|
7
8
|
Magickly::App
|
8
9
|
end
|
9
10
|
|
11
|
+
def setup_image(host='http://www.foo.com')
|
12
|
+
@image_filename = 'imagemagick.png'
|
13
|
+
@image_url = "#{host}/#{@image_filename}"
|
14
|
+
@image_path = File.join(File.dirname(__FILE__), '..', 'support', @image_filename)
|
15
|
+
stub_request(:get, @image_url).to_return(:body => File.new(@image_path))
|
16
|
+
end
|
17
|
+
|
10
18
|
describe "GET /" do
|
11
|
-
def setup_image(host='http://www.foo.com')
|
12
|
-
@image_filename = 'imagemagick.png'
|
13
|
-
@image_url = "#{host}/#{@image_filename}"
|
14
|
-
@image_path = File.join(File.dirname(__FILE__), '..', 'support', @image_filename)
|
15
|
-
stub_request(:get, @image_url).to_return(:body => File.new(@image_path))
|
16
|
-
end
|
17
|
-
|
18
19
|
it "should display the demo page for no params" do
|
19
20
|
get '/'
|
20
21
|
last_response.should be_ok
|
@@ -100,6 +101,42 @@ describe Magickly::App do
|
|
100
101
|
ImageSize.new(last_response.body).get_width.should eq width
|
101
102
|
end
|
102
103
|
end
|
104
|
+
|
105
|
+
describe "GET /analyze" do
|
106
|
+
it "retrieves the mime_type of an image" do
|
107
|
+
setup_image
|
108
|
+
|
109
|
+
get "/analyze/mime_type?src=#{@image_url}"
|
110
|
+
|
111
|
+
a_request(:get, @image_url).should have_been_made.once
|
112
|
+
last_response.should be_ok
|
113
|
+
last_response.body.should eq 'image/png'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "retrieves the color palette of an image" do
|
117
|
+
setup_image
|
118
|
+
|
119
|
+
get "/analyze/color_palette?src=#{@image_url}"
|
120
|
+
|
121
|
+
a_request(:get, @image_url).should have_been_made.once
|
122
|
+
last_response.should be_ok
|
123
|
+
last_response.body.should_not be_empty
|
124
|
+
json = JSON.parse(last_response.body)
|
125
|
+
json.should be_an Array
|
126
|
+
json.size.should eq 5
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should handle analyzer methods where the question mark is missing" do
|
130
|
+
Magickly.dragonfly.analyser_methods.map{|m| m.to_s }.should include 'landscape?'
|
131
|
+
setup_image
|
132
|
+
|
133
|
+
get "/analyze/landscape?src=#{@image_url}"
|
134
|
+
|
135
|
+
a_request(:get, @image_url).should have_been_made.once
|
136
|
+
last_response.should be_ok
|
137
|
+
last_response.body.should =~ /false/
|
138
|
+
end
|
139
|
+
end
|
103
140
|
end
|
104
141
|
|
105
142
|
describe MagicklyApp do
|
data/spec/spec_helper.rb
CHANGED
@@ -8,7 +8,7 @@ require 'image_size'
|
|
8
8
|
|
9
9
|
# Requires supporting files with custom matchers and macros, etc,
|
10
10
|
# in ./support/ and its subdirectories.
|
11
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
11
|
+
# Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
12
|
|
13
13
|
set :environment, :test
|
14
14
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Dragonfly shortcuts" do
|
4
|
+
before do
|
5
|
+
@image_path = File.join(File.dirname(__FILE__), '..', 'support', 'imagemagick.png')
|
6
|
+
@image = Magickly.dragonfly.fetch_file(@image_path)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe :brightness_contrast do
|
10
|
+
it "should throw an error for no arguments" do
|
11
|
+
expect { @image.brightness_contrast }.to raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should throw an error for a empty string" do
|
15
|
+
expect { @image.brightness_contrast('') }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should succeed for a valid argument" do
|
19
|
+
@image.brightness_contrast('10x10')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should succeed for negative values" do
|
23
|
+
@image.brightness_contrast('-80x-80')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe :color_palette do
|
28
|
+
it "should return an array" do
|
29
|
+
palette = @image.color_palette
|
30
|
+
palette.should be_an Array
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have the default number of colors" do
|
34
|
+
palette = @image.color_palette
|
35
|
+
palette.length.should eq Magickly::DEFAULT_PALETTE_COLOR_COUNT
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have the specified number of colors" do
|
39
|
+
num_colors = 4
|
40
|
+
num_colors.should_not eq Magickly::DEFAULT_PALETTE_COLOR_COUNT
|
41
|
+
|
42
|
+
palette = @image.color_palette(num_colors)
|
43
|
+
palette.length.should eq num_colors
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe :tilt_shift do
|
48
|
+
it "should throw an error for no coefficient" do
|
49
|
+
expect { @image.tilt_shift }.to raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should throw an error for a empty string" do
|
53
|
+
expect { @image.tilt_shift('') }.to raise_error(ArgumentError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should succeed for a valid coefficient" do
|
57
|
+
@image.tilt_shift('2,-1,0.5')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magickly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 1.2.0
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Aidan Feldman
|
@@ -10,141 +15,205 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
14
|
-
default_executable: magickly
|
18
|
+
date: 2011-06-29 00:00:00 Z
|
15
19
|
dependencies:
|
16
20
|
- !ruby/object:Gem::Dependency
|
17
|
-
|
18
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
19
22
|
none: false
|
20
23
|
requirements:
|
21
24
|
- - ~>
|
22
25
|
- !ruby/object:Gem::Version
|
26
|
+
hash: 29
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
- 1
|
23
31
|
version: 1.2.1
|
24
32
|
type: :runtime
|
33
|
+
requirement: *id001
|
25
34
|
prerelease: false
|
26
|
-
|
35
|
+
name: sinatra
|
27
36
|
- !ruby/object:Gem::Dependency
|
28
|
-
|
29
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
30
38
|
none: false
|
31
39
|
requirements:
|
32
40
|
- - ~>
|
33
41
|
- !ruby/object:Gem::Version
|
42
|
+
hash: 57
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 9
|
46
|
+
- 1
|
34
47
|
version: 0.9.1
|
35
48
|
type: :runtime
|
49
|
+
requirement: *id002
|
36
50
|
prerelease: false
|
37
|
-
|
51
|
+
name: dragonfly
|
38
52
|
- !ruby/object:Gem::Dependency
|
39
|
-
|
40
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
41
54
|
none: false
|
42
55
|
requirements:
|
43
56
|
- - ~>
|
44
57
|
- !ruby/object:Gem::Version
|
58
|
+
hash: 7
|
59
|
+
segments:
|
60
|
+
- 2
|
61
|
+
- 2
|
45
62
|
version: "2.2"
|
46
63
|
type: :runtime
|
64
|
+
requirement: *id003
|
47
65
|
prerelease: false
|
48
|
-
|
66
|
+
name: addressable
|
49
67
|
- !ruby/object:Gem::Dependency
|
50
|
-
|
51
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
52
69
|
none: false
|
53
70
|
requirements:
|
54
71
|
- - ~>
|
55
72
|
- !ruby/object:Gem::Version
|
73
|
+
hash: 7
|
74
|
+
segments:
|
75
|
+
- 3
|
76
|
+
- 0
|
56
77
|
version: "3.0"
|
57
78
|
type: :runtime
|
79
|
+
requirement: *id004
|
58
80
|
prerelease: false
|
59
|
-
|
81
|
+
name: haml
|
60
82
|
- !ruby/object:Gem::Dependency
|
61
|
-
|
62
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
63
84
|
none: false
|
64
85
|
requirements:
|
65
86
|
- - ~>
|
66
87
|
- !ruby/object:Gem::Version
|
88
|
+
hash: 5
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
- 7
|
92
|
+
- 3
|
67
93
|
version: 0.7.3
|
68
94
|
type: :runtime
|
95
|
+
requirement: *id005
|
69
96
|
prerelease: false
|
70
|
-
|
97
|
+
name: httparty
|
71
98
|
- !ruby/object:Gem::Dependency
|
72
|
-
|
73
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
99
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
74
100
|
none: false
|
75
101
|
requirements:
|
76
102
|
- - ">="
|
77
103
|
- !ruby/object:Gem::Version
|
104
|
+
hash: 15
|
105
|
+
segments:
|
106
|
+
- 2
|
107
|
+
- 0
|
108
|
+
- 0
|
78
109
|
version: 2.0.0
|
79
110
|
type: :runtime
|
111
|
+
requirement: *id006
|
80
112
|
prerelease: false
|
81
|
-
|
113
|
+
name: activesupport
|
82
114
|
- !ruby/object:Gem::Dependency
|
83
|
-
|
84
|
-
|
115
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ~>
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
hash: 5
|
121
|
+
segments:
|
122
|
+
- 1
|
123
|
+
- 5
|
124
|
+
version: "1.5"
|
125
|
+
type: :runtime
|
126
|
+
requirement: *id007
|
127
|
+
prerelease: false
|
128
|
+
name: json
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
85
131
|
none: false
|
86
132
|
requirements:
|
87
133
|
- - ~>
|
88
134
|
- !ruby/object:Gem::Version
|
135
|
+
hash: 5
|
136
|
+
segments:
|
137
|
+
- 1
|
138
|
+
- 5
|
89
139
|
version: "1.5"
|
90
140
|
type: :development
|
141
|
+
requirement: *id008
|
91
142
|
prerelease: false
|
92
|
-
|
143
|
+
name: jeweler
|
93
144
|
- !ruby/object:Gem::Dependency
|
94
|
-
|
95
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
145
|
+
version_requirements: &id009 !ruby/object:Gem::Requirement
|
96
146
|
none: false
|
97
147
|
requirements:
|
98
148
|
- - ">="
|
99
149
|
- !ruby/object:Gem::Version
|
150
|
+
hash: 3
|
151
|
+
segments:
|
152
|
+
- 0
|
100
153
|
version: "0"
|
101
154
|
type: :development
|
155
|
+
requirement: *id009
|
102
156
|
prerelease: false
|
103
|
-
|
157
|
+
name: rcov
|
104
158
|
- !ruby/object:Gem::Dependency
|
105
|
-
|
106
|
-
requirement: &id009 !ruby/object:Gem::Requirement
|
159
|
+
version_requirements: &id010 !ruby/object:Gem::Requirement
|
107
160
|
none: false
|
108
161
|
requirements:
|
109
162
|
- - ">="
|
110
163
|
- !ruby/object:Gem::Version
|
164
|
+
hash: 3
|
165
|
+
segments:
|
166
|
+
- 0
|
111
167
|
version: "0"
|
112
168
|
type: :development
|
169
|
+
requirement: *id010
|
113
170
|
prerelease: false
|
114
|
-
|
171
|
+
name: rack-test
|
115
172
|
- !ruby/object:Gem::Dependency
|
116
|
-
|
117
|
-
requirement: &id010 !ruby/object:Gem::Requirement
|
173
|
+
version_requirements: &id011 !ruby/object:Gem::Requirement
|
118
174
|
none: false
|
119
175
|
requirements:
|
120
176
|
- - ~>
|
121
177
|
- !ruby/object:Gem::Version
|
178
|
+
hash: 11
|
179
|
+
segments:
|
180
|
+
- 2
|
181
|
+
- 4
|
122
182
|
version: "2.4"
|
123
183
|
type: :development
|
184
|
+
requirement: *id011
|
124
185
|
prerelease: false
|
125
|
-
|
186
|
+
name: rspec
|
126
187
|
- !ruby/object:Gem::Dependency
|
127
|
-
|
128
|
-
requirement: &id011 !ruby/object:Gem::Requirement
|
188
|
+
version_requirements: &id012 !ruby/object:Gem::Requirement
|
129
189
|
none: false
|
130
190
|
requirements:
|
131
191
|
- - ~>
|
132
192
|
- !ruby/object:Gem::Version
|
193
|
+
hash: 3
|
194
|
+
segments:
|
195
|
+
- 1
|
196
|
+
- 6
|
133
197
|
version: "1.6"
|
134
198
|
type: :development
|
199
|
+
requirement: *id012
|
135
200
|
prerelease: false
|
136
|
-
|
201
|
+
name: webmock
|
137
202
|
- !ruby/object:Gem::Dependency
|
138
|
-
|
139
|
-
requirement: &id012 !ruby/object:Gem::Requirement
|
203
|
+
version_requirements: &id013 !ruby/object:Gem::Requirement
|
140
204
|
none: false
|
141
205
|
requirements:
|
142
206
|
- - ~>
|
143
207
|
- !ruby/object:Gem::Version
|
208
|
+
hash: 9
|
209
|
+
segments:
|
210
|
+
- 0
|
211
|
+
- 1
|
144
212
|
version: "0.1"
|
145
213
|
type: :development
|
214
|
+
requirement: *id013
|
146
215
|
prerelease: false
|
147
|
-
|
216
|
+
name: imagesize
|
148
217
|
description: A service for image manipulation - built as an extensible wrapper of Imagemagick which handles caching, c/o the Dragonfly gem.
|
149
218
|
email: aidan.feldman@gmail.com
|
150
219
|
executables:
|
@@ -167,11 +236,14 @@ files:
|
|
167
236
|
- VERSION
|
168
237
|
- bin/magickly
|
169
238
|
- config.ru
|
239
|
+
- lib/dragonfly/app.rb
|
170
240
|
- lib/dragonfly/data_storage/remote_data_store.rb
|
241
|
+
- lib/images/lomo_mask.png
|
171
242
|
- lib/magickly.rb
|
172
243
|
- lib/magickly/app.rb
|
173
244
|
- lib/public/imagemagick.png
|
174
245
|
- lib/shortcuts.rb
|
246
|
+
- lib/views/analyzers.haml
|
175
247
|
- lib/views/index.haml
|
176
248
|
- magickly.gemspec
|
177
249
|
- spec/requests/magickly_app_spec.rb
|
@@ -179,7 +251,7 @@ files:
|
|
179
251
|
- spec/support/imagemagick.png
|
180
252
|
- spec/unit/magickly_spec.rb
|
181
253
|
- spec/unit/remote_data_store_spec.rb
|
182
|
-
|
254
|
+
- spec/unit/shortcut_spec.rb
|
183
255
|
homepage: http://github.com/afeld/magickly
|
184
256
|
licenses:
|
185
257
|
- MIT
|
@@ -193,7 +265,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
193
265
|
requirements:
|
194
266
|
- - ">="
|
195
267
|
- !ruby/object:Gem::Version
|
196
|
-
hash:
|
268
|
+
hash: 3
|
197
269
|
segments:
|
198
270
|
- 0
|
199
271
|
version: "0"
|
@@ -202,11 +274,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
274
|
requirements:
|
203
275
|
- - ">="
|
204
276
|
- !ruby/object:Gem::Version
|
277
|
+
hash: 3
|
278
|
+
segments:
|
279
|
+
- 0
|
205
280
|
version: "0"
|
206
281
|
requirements: []
|
207
282
|
|
208
283
|
rubyforge_project:
|
209
|
-
rubygems_version: 1.
|
284
|
+
rubygems_version: 1.8.5
|
210
285
|
signing_key:
|
211
286
|
specification_version: 3
|
212
287
|
summary: image manipulation as a (plugin-able) service
|