imagga 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +53 -0
- data/Rakefile +6 -0
- data/imagga.gemspec +25 -0
- data/lib/imagga.rb +7 -0
- data/lib/imagga/client.rb +42 -0
- data/lib/imagga/exceptions.rb +21 -0
- data/lib/imagga/extract_options.rb +74 -0
- data/lib/imagga/extract_result_builder.rb +11 -0
- data/lib/imagga/image.rb +71 -0
- data/lib/imagga/rank_result_builder.rb +9 -0
- data/lib/imagga/version.rb +3 -0
- data/spec/lib/client_spec.rb +352 -0
- data/spec/lib/extract_result_builder_spec.rb +25 -0
- data/spec/lib/extraction_options_spec.rb +73 -0
- data/spec/lib/image_color_spec.rb +58 -0
- data/spec/lib/image_info_spec.rb +88 -0
- data/spec/lib/image_spec.rb +25 -0
- data/spec/lib/rank_result_builder_spec.rb +25 -0
- data/spec/lib/rank_similarity_spec.rb +31 -0
- data/spec/spec_helper.rb +11 -0
- metadata +165 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Mart Karu
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/martkaru/imagga.png?branch=master)](https://travis-ci.org/martkaru/imagga)
|
2
|
+
|
3
|
+
# Imagga
|
4
|
+
|
5
|
+
Client for Imagga image analytics services API
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'imagga'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install imagga
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Set up a client
|
24
|
+
|
25
|
+
client = Imagga::Client.new(
|
26
|
+
base_uri: '0.0.0.0', # IP of the Imagga server
|
27
|
+
api_key: '12345678', # Your api key
|
28
|
+
api_secret: '1234567890123456789' # Your api secret
|
29
|
+
)
|
30
|
+
|
31
|
+
Extract image information
|
32
|
+
|
33
|
+
results = client.extract('http://imagga.com/images/scheme_colors.png')
|
34
|
+
|
35
|
+
Extract image information with indexing and extraction options:
|
36
|
+
|
37
|
+
results = client.extract(
|
38
|
+
[
|
39
|
+
Imagga::Image.new(url: 'http://image1', id: '333'),
|
40
|
+
Imagga::Image.new(url: 'http://image2')
|
41
|
+
],
|
42
|
+
extract_overall_colors: true,
|
43
|
+
extract_object_colors: false
|
44
|
+
)
|
45
|
+
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
1. Fork it
|
50
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
52
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
53
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/imagga.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'imagga/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "imagga"
|
8
|
+
gem.version = Imagga::VERSION
|
9
|
+
gem.authors = ["Mart Karu"]
|
10
|
+
gem.email = ["karu@metal.ee"]
|
11
|
+
gem.description = %q{Ruby client for accessing Imagga API}
|
12
|
+
gem.summary = %q{Ruby client for accessing Imagga API}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
gem.add_dependency "httparty", "~> 0.10"
|
20
|
+
gem.add_dependency "json", "~> 1.7"
|
21
|
+
|
22
|
+
gem.add_development_dependency "rspec", "~> 2.12"
|
23
|
+
gem.add_development_dependency "rake"
|
24
|
+
gem.add_development_dependency "fakeweb"
|
25
|
+
end
|
data/lib/imagga.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require "httparty"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Imagga
|
5
|
+
class Client
|
6
|
+
include HTTParty
|
7
|
+
include Imagga::Exceptions
|
8
|
+
attr_reader :api_key, :api_secret, :base_uri, :service_path
|
9
|
+
|
10
|
+
def initialize(opts={})
|
11
|
+
@api_key = opts[:api_key] || raise_missing(:api_key)
|
12
|
+
@api_secret = opts[:api_secret] || raise_missing(:api_secret)
|
13
|
+
@base_uri = opts[:base_uri] || raise_missing(:base_uri)
|
14
|
+
@service_path = '/colorsearchserver.php'
|
15
|
+
|
16
|
+
Imagga::Client.base_uri @base_uri
|
17
|
+
end
|
18
|
+
|
19
|
+
def extract(urls_or_images, additional_options={})
|
20
|
+
options = extract_options(urls_or_images, additional_options)
|
21
|
+
result = JSON.parse(self.class.post(service_path, body: options))
|
22
|
+
raise_if_request_failed!(result)
|
23
|
+
ExtractResultBuilder.new.build_from(result)
|
24
|
+
end
|
25
|
+
|
26
|
+
def rank(opts)
|
27
|
+
result = JSON.parse(self.class.post(service_path, body: rank_options(opts)))
|
28
|
+
raise_if_request_failed!(result)
|
29
|
+
RankResultBuilder.new.build_from(result)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def extract_options(urls_or_images, additional_options)
|
35
|
+
ExtractOptions.new(api_key, api_secret).options(urls_or_images, additional_options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def rank_options(opts)
|
39
|
+
RankOptions.new(api_key, api_secret).options(opts)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Imagga
|
2
|
+
module Exceptions
|
3
|
+
def raise_missing(attribute)
|
4
|
+
raise ArgumentError, "%s is missing" % attribute.to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
def raise_if_request_failed!(result)
|
8
|
+
if result.respond_to?(:keys) && result.keys.include?('error_code')
|
9
|
+
raise Imagga::ClientException.new(result['error_code'].to_i), result['error_message'], caller[0..-1]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ClientException < StandardError
|
15
|
+
attr_accessor :error_code
|
16
|
+
def initialize(error_code)
|
17
|
+
@error_code = error_code
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Imagga
|
2
|
+
class BaseOptions
|
3
|
+
attr_accessor :api_key, :api_secret
|
4
|
+
|
5
|
+
def initialize(api_key, api_secret)
|
6
|
+
@version = '1.0'
|
7
|
+
@api_key = api_key || raise_missing(:api_key)
|
8
|
+
@api_secret = api_secret || raise_missing(:api_secret)
|
9
|
+
end
|
10
|
+
|
11
|
+
def base_options
|
12
|
+
{ v: @version, api_key: @api_key }
|
13
|
+
end
|
14
|
+
|
15
|
+
def sign(options)
|
16
|
+
sorted_options_string = options.keys.sort.map do |key|
|
17
|
+
"%s=%s" % [key.to_s, options[key]]
|
18
|
+
end.join('') << @api_secret
|
19
|
+
Digest::MD5.hexdigest(sorted_options_string)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class ExtractOptions < BaseOptions
|
24
|
+
|
25
|
+
def options(urls_or_images, additional_options={})
|
26
|
+
options = base_options.merge(
|
27
|
+
method: 'imagga.colorsearch.extract',
|
28
|
+
urls: build_urls(urls_or_images),
|
29
|
+
)
|
30
|
+
|
31
|
+
if ids = build_ids(urls_or_images)
|
32
|
+
options.merge!(ids: ids)
|
33
|
+
end
|
34
|
+
|
35
|
+
[:extract_overall_colors, :extract_object_colors].each do |key|
|
36
|
+
if additional_options.keys.include?(key) && (value = additional_options[key] ? 1 : 0)
|
37
|
+
options.merge!(key => value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
options.merge!(sig: sign(options))
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_urls(urls_or_images)
|
45
|
+
[urls_or_images].flatten.map{ |o| o.url rescue o }.join(',')
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_ids(urls_or_images)
|
49
|
+
ids = [urls_or_images].flatten.map{ |o| o.id rescue 0 }
|
50
|
+
return if ids.uniq == [0]
|
51
|
+
ids.join(',')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class RankOptions < BaseOptions
|
57
|
+
def options(opts)
|
58
|
+
color_vector = opts.fetch(:color_vector)
|
59
|
+
type = opts.fetch(:type)
|
60
|
+
dist = opts.fetch(:dist)
|
61
|
+
count = opts.fetch(:count)
|
62
|
+
|
63
|
+
options = base_options.merge(
|
64
|
+
method: 'imagga.colorsearch.rank',
|
65
|
+
color_vector: color_vector,
|
66
|
+
type: type,
|
67
|
+
dist: dist,
|
68
|
+
count: count
|
69
|
+
)
|
70
|
+
|
71
|
+
options.merge!(sig: sign(options))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/imagga/image.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
module Imagga
|
2
|
+
class Image
|
3
|
+
include Imagga::Exceptions
|
4
|
+
attr_accessor :url, :id
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
@url = opts[:url] || raise_missing(:url)
|
8
|
+
@id = opts[:id] || 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ImageInfoBase
|
13
|
+
def initialize(opts={})
|
14
|
+
self.class.fields.each { |field| send("#{field}=", opts[field]) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ImageInfo < ImageInfoBase
|
19
|
+
def self.fields
|
20
|
+
%w(url object_percentage color_variance image_packed foreground_packed background_packed)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.color_fields
|
24
|
+
%w(image_colors foreground_colors background_colors)
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(opts={})
|
28
|
+
super(opts['info'].merge('url' => opts['url']))
|
29
|
+
self.class.color_fields.each do |field|
|
30
|
+
send("#{field}=", build_image_colors(opts['info'][field]))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_image_colors(image_color_nodes)
|
35
|
+
image_color_nodes && image_color_nodes.map { |color_node| ImageColor.new(color_node) }
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor *(fields + color_fields)
|
39
|
+
|
40
|
+
def color_variance=(value)
|
41
|
+
@color_variance = value.to_i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class ImageColor < ImageInfoBase
|
46
|
+
def self.fields
|
47
|
+
%w(percent r g b html_code closest_palette_color closest_palette_color_parent closest_palette_distance)
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor *fields
|
51
|
+
|
52
|
+
%w(r g b).each do |field|
|
53
|
+
define_method("#{field}=") do |value|
|
54
|
+
instance_variable_set("@#{field}", value.to_i)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def percent=(value)
|
59
|
+
@percent = value.to_f
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
class RankSimilarity < ImageInfoBase
|
65
|
+
def self.fields
|
66
|
+
%w(id dist)
|
67
|
+
end
|
68
|
+
|
69
|
+
attr_accessor *fields
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fake_web'
|
3
|
+
|
4
|
+
describe Imagga::Client do
|
5
|
+
|
6
|
+
subject { described_class.new(api_key: '1', api_secret: '2', base_uri: 'http://example.com') }
|
7
|
+
let(:extract_response) {'{
|
8
|
+
"colors":[
|
9
|
+
{
|
10
|
+
"url":"http:\/\/www.stockpodium.com\/stock-photo-8244245\/smiling-presenting-2-apples-image.jpg",
|
11
|
+
"info":{
|
12
|
+
"image_colors":[
|
13
|
+
{
|
14
|
+
"percent":"38.90",
|
15
|
+
"r":"247",
|
16
|
+
"g":"245",
|
17
|
+
"b":"243",
|
18
|
+
"html_code":"#f7f5f3",
|
19
|
+
"closest_palette_color":"white",
|
20
|
+
"closest_palette_color_parent":"white",
|
21
|
+
"closest_palette_distance":1.8304102578
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"percent":"35.16",
|
25
|
+
"r":"206",
|
26
|
+
"g":"167",
|
27
|
+
"b":"146",
|
28
|
+
"html_code":"#cea792",
|
29
|
+
"closest_palette_color":"fresco",
|
30
|
+
"closest_palette_color_parent":"beige",
|
31
|
+
"closest_palette_distance":4.93287465177
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"percent":"10.41",
|
35
|
+
"r":"150",
|
36
|
+
"g":"60",
|
37
|
+
"b":"45",
|
38
|
+
"html_code":"#963c2d",
|
39
|
+
"closest_palette_color":"ribbon red",
|
40
|
+
"closest_palette_color_parent":"red",
|
41
|
+
"closest_palette_distance":5.6423821179
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"percent":"8.38",
|
45
|
+
"r":"55",
|
46
|
+
"g":"37",
|
47
|
+
"b":"31",
|
48
|
+
"html_code":"#37251f",
|
49
|
+
"closest_palette_color":"espresso",
|
50
|
+
"closest_palette_color_parent":"brown",
|
51
|
+
"closest_palette_distance":5.91329502182
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"percent":"7.15",
|
55
|
+
"r":"168",
|
56
|
+
"g":"181",
|
57
|
+
"b":"45",
|
58
|
+
"html_code":"#a8b52d",
|
59
|
+
"closest_palette_color":"mint",
|
60
|
+
"closest_palette_color_parent":"olive green",
|
61
|
+
"closest_palette_distance":10.7126507469
|
62
|
+
}
|
63
|
+
],
|
64
|
+
"foreground_colors":[
|
65
|
+
{
|
66
|
+
"percent":"45.92",
|
67
|
+
"r":"200",
|
68
|
+
"g":"180",
|
69
|
+
"b":"112",
|
70
|
+
"html_code":"#c8b470",
|
71
|
+
"closest_palette_color":"medium olive",
|
72
|
+
"closest_palette_color_parent":"skin",
|
73
|
+
"closest_palette_distance":7.22056402093
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"percent":"34.21",
|
77
|
+
"r":"162",
|
78
|
+
"g":"79",
|
79
|
+
"b":"61",
|
80
|
+
"html_code":"#a24f3d",
|
81
|
+
"closest_palette_color":"fiesta",
|
82
|
+
"closest_palette_color_parent":"red",
|
83
|
+
"closest_palette_distance":6.29194294147
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"percent":"19.86",
|
87
|
+
"r":"52",
|
88
|
+
"g":"35",
|
89
|
+
"b":"31",
|
90
|
+
"html_code":"#34231f",
|
91
|
+
"closest_palette_color":"espresso",
|
92
|
+
"closest_palette_color_parent":"brown",
|
93
|
+
"closest_palette_distance":6.49089812519
|
94
|
+
}
|
95
|
+
],
|
96
|
+
"background_colors":[
|
97
|
+
{
|
98
|
+
"percent":"58.05",
|
99
|
+
"r":"249",
|
100
|
+
"g":"248",
|
101
|
+
"b":"247",
|
102
|
+
"html_code":"#f9f8f7",
|
103
|
+
"closest_palette_color":"white",
|
104
|
+
"closest_palette_color_parent":"white",
|
105
|
+
"closest_palette_distance":2.48109615666
|
106
|
+
},
|
107
|
+
{
|
108
|
+
"percent":"36.41",
|
109
|
+
"r":"206",
|
110
|
+
"g":"177",
|
111
|
+
"b":"161",
|
112
|
+
"html_code":"#ceb1a1",
|
113
|
+
"closest_palette_color":"pearl pink",
|
114
|
+
"closest_palette_color_parent":"light pink",
|
115
|
+
"closest_palette_distance":4.11506425614
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"percent":"5.55",
|
119
|
+
"r":"150",
|
120
|
+
"g":"100",
|
121
|
+
"b":"77",
|
122
|
+
"html_code":"#96644d",
|
123
|
+
"closest_palette_color":"light bronze",
|
124
|
+
"closest_palette_color_parent":"skin",
|
125
|
+
"closest_palette_distance":6.37479340147
|
126
|
+
}
|
127
|
+
],
|
128
|
+
"object_percentage":38.4,
|
129
|
+
"color_variance":"33"
|
130
|
+
}
|
131
|
+
},
|
132
|
+
{
|
133
|
+
"url":"http:\/\/www.stockpodium.com\/stock-photo-9289532\/car-dirving-very-fast-under-image.jpg",
|
134
|
+
"info":{
|
135
|
+
"image_colors":[
|
136
|
+
{
|
137
|
+
"percent":"38.53",
|
138
|
+
"r":"103",
|
139
|
+
"g":"98",
|
140
|
+
"b":"98",
|
141
|
+
"html_code":"#676262",
|
142
|
+
"closest_palette_color":"blue steel",
|
143
|
+
"closest_palette_color_parent":"grey",
|
144
|
+
"closest_palette_distance":10.486937593
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"percent":"26.31",
|
148
|
+
"r":"42",
|
149
|
+
"g":"37",
|
150
|
+
"b":"33",
|
151
|
+
"html_code":"#2a2521",
|
152
|
+
"closest_palette_color":"espresso",
|
153
|
+
"closest_palette_color_parent":"brown",
|
154
|
+
"closest_palette_distance":8.14492880108
|
155
|
+
},
|
156
|
+
{
|
157
|
+
"percent":"16.19",
|
158
|
+
"r":"178",
|
159
|
+
"g":"182",
|
160
|
+
"b":"190",
|
161
|
+
"html_code":"#b2b6be",
|
162
|
+
"closest_palette_color":"frost",
|
163
|
+
"closest_palette_color_parent":"light grey",
|
164
|
+
"closest_palette_distance":2.82095071372
|
165
|
+
},
|
166
|
+
{
|
167
|
+
"percent":"12.06",
|
168
|
+
"r":"197",
|
169
|
+
"g":"51",
|
170
|
+
"b":"45",
|
171
|
+
"html_code":"#c5332d",
|
172
|
+
"closest_palette_color":"fiesta",
|
173
|
+
"closest_palette_color_parent":"red",
|
174
|
+
"closest_palette_distance":5.41278686601
|
175
|
+
},
|
176
|
+
{
|
177
|
+
"percent":"6.91",
|
178
|
+
"r":"86",
|
179
|
+
"g":"97",
|
180
|
+
"b":"28",
|
181
|
+
"html_code":"#56611c",
|
182
|
+
"closest_palette_color":"moss",
|
183
|
+
"closest_palette_color_parent":"olive green",
|
184
|
+
"closest_palette_distance":9.97695248255
|
185
|
+
}
|
186
|
+
],
|
187
|
+
"foreground_colors":[
|
188
|
+
{
|
189
|
+
"percent":"62.98",
|
190
|
+
"r":"199",
|
191
|
+
"g":"50",
|
192
|
+
"b":"43",
|
193
|
+
"html_code":"#c7322b",
|
194
|
+
"closest_palette_color":"fiesta",
|
195
|
+
"closest_palette_color_parent":"red",
|
196
|
+
"closest_palette_distance":5.44027296941
|
197
|
+
},
|
198
|
+
{
|
199
|
+
"percent":"22.01",
|
200
|
+
"r":"140",
|
201
|
+
"g":"132",
|
202
|
+
"b":"144",
|
203
|
+
"html_code":"#8c8490",
|
204
|
+
"closest_palette_color":"shadow",
|
205
|
+
"closest_palette_color_parent":"light grey",
|
206
|
+
"closest_palette_distance":3.40761167276
|
207
|
+
},
|
208
|
+
{
|
209
|
+
"percent":"15.01",
|
210
|
+
"r":"61",
|
211
|
+
"g":"38",
|
212
|
+
"b":"43",
|
213
|
+
"html_code":"#3d262b",
|
214
|
+
"closest_palette_color":"espresso",
|
215
|
+
"closest_palette_color_parent":"brown",
|
216
|
+
"closest_palette_distance":5.85441000013
|
217
|
+
}
|
218
|
+
],
|
219
|
+
"background_colors":[
|
220
|
+
{
|
221
|
+
"percent":"41.07",
|
222
|
+
"r":"103",
|
223
|
+
"g":"97",
|
224
|
+
"b":"97",
|
225
|
+
"html_code":"#676161",
|
226
|
+
"closest_palette_color":"blue steel",
|
227
|
+
"closest_palette_color_parent":"grey",
|
228
|
+
"closest_palette_distance":10.6345471176
|
229
|
+
},
|
230
|
+
{
|
231
|
+
"percent":"39.63",
|
232
|
+
"r":"53",
|
233
|
+
"g":"51",
|
234
|
+
"b":"34",
|
235
|
+
"html_code":"#353322",
|
236
|
+
"closest_palette_color":"graphite",
|
237
|
+
"closest_palette_color_parent":"black",
|
238
|
+
"closest_palette_distance":9.18317865786
|
239
|
+
},
|
240
|
+
{
|
241
|
+
"percent":"19.29",
|
242
|
+
"r":"174",
|
243
|
+
"g":"180",
|
244
|
+
"b":"187",
|
245
|
+
"html_code":"#aeb4bb",
|
246
|
+
"closest_palette_color":"frost",
|
247
|
+
"closest_palette_color_parent":"light grey",
|
248
|
+
"closest_palette_distance":2.03931376316
|
249
|
+
}
|
250
|
+
],
|
251
|
+
"object_percentage":17.99,
|
252
|
+
"color_variance":"37",
|
253
|
+
"image_packed":null,
|
254
|
+
"foreground_packed":null,
|
255
|
+
"background_packed":null
|
256
|
+
}
|
257
|
+
}
|
258
|
+
]
|
259
|
+
}'}
|
260
|
+
|
261
|
+
let(:rank_response) { '{
|
262
|
+
"rank_similarity":[
|
263
|
+
{
|
264
|
+
"id":8774077,
|
265
|
+
"dist":2597.38299
|
266
|
+
},
|
267
|
+
{
|
268
|
+
"id":9085916,
|
269
|
+
"dist":2681.33259
|
270
|
+
}
|
271
|
+
]
|
272
|
+
}'}
|
273
|
+
|
274
|
+
let(:failed_signature_response) { '{"error_code":3,"error_message":"Invalid signature"}' }
|
275
|
+
|
276
|
+
it "has api_key" do
|
277
|
+
subject.api_key.should == '1'
|
278
|
+
end
|
279
|
+
|
280
|
+
it "has api_secret" do
|
281
|
+
subject.api_secret.should == '2'
|
282
|
+
end
|
283
|
+
|
284
|
+
it "has base_uri" do
|
285
|
+
subject.base_uri.should == 'http://example.com'
|
286
|
+
end
|
287
|
+
|
288
|
+
it "knows service path" do
|
289
|
+
subject.service_path.should == '/colorsearchserver.php'
|
290
|
+
end
|
291
|
+
|
292
|
+
describe "#extract" do
|
293
|
+
it "extracts image info" do
|
294
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: extract_response)
|
295
|
+
subject.extract('http://image').size.should == 2
|
296
|
+
end
|
297
|
+
|
298
|
+
context "with failing request" do
|
299
|
+
before :each do
|
300
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: failed_signature_response)
|
301
|
+
subject.should_receive(:extract_options).with('http://image', {})
|
302
|
+
end
|
303
|
+
|
304
|
+
it "raises exception" do
|
305
|
+
expect { subject.extract('http://image') }.to raise_error(Imagga::ClientException)
|
306
|
+
end
|
307
|
+
|
308
|
+
it "populates exception object with details" do
|
309
|
+
begin
|
310
|
+
subject.extract('http://image')
|
311
|
+
rescue Imagga::ClientException => e
|
312
|
+
e.message.should == 'Invalid signature'
|
313
|
+
e.error_code.should == 3
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "#rank" do
|
320
|
+
let(:rank_arguments) { {
|
321
|
+
color_vector: [{percent: 60, r: 255, g: 0, b: 0}],
|
322
|
+
type: 'overall',
|
323
|
+
dist: 3000,
|
324
|
+
count: 200
|
325
|
+
} }
|
326
|
+
|
327
|
+
it "does a rank search" do
|
328
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: rank_response)
|
329
|
+
subject.rank(rank_arguments).size.should == 2
|
330
|
+
end
|
331
|
+
|
332
|
+
context "with failing request" do
|
333
|
+
before :each do
|
334
|
+
FakeWeb.register_uri(:post, 'http://example.com/colorsearchserver.php', body: failed_signature_response)
|
335
|
+
subject.should_receive(:rank_options)
|
336
|
+
end
|
337
|
+
|
338
|
+
it "raises exception" do
|
339
|
+
expect { subject.rank(rank_arguments) }.to raise_error(Imagga::ClientException)
|
340
|
+
end
|
341
|
+
|
342
|
+
it "populates exception object with details" do
|
343
|
+
begin
|
344
|
+
subject.rank(rank_arguments)
|
345
|
+
rescue Imagga::ClientException => e
|
346
|
+
e.message.should == 'Invalid signature'
|
347
|
+
e.error_code.should == 3
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ExtractResultBuilder do
|
4
|
+
let(:result) { {
|
5
|
+
"colors" => [
|
6
|
+
{
|
7
|
+
"url" =>"http:\/\/www.stockpodium.com\/stock-photo-8244245\/smiling-presenting-2-apples-image.jpg",
|
8
|
+
"info" => {}
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"url" =>"http:\/\/www.stockpodium.com\/stock-photo-9289532\/car-dirving-very-fast-under-image.jpg",
|
12
|
+
"info" => {}
|
13
|
+
}
|
14
|
+
]
|
15
|
+
} }
|
16
|
+
|
17
|
+
subject { described_class.new }
|
18
|
+
|
19
|
+
describe '#build' do
|
20
|
+
it "builds result" do
|
21
|
+
subject.build_from(result).size.should == 2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ExtractOptions do
|
4
|
+
subject { described_class.new('apikey', 'secret') }
|
5
|
+
|
6
|
+
describe "#options" do
|
7
|
+
it "builds simple options" do
|
8
|
+
subject.options('http://image').should == {
|
9
|
+
urls: 'http://image',
|
10
|
+
method: 'imagga.colorsearch.extract',
|
11
|
+
sig: '76e667179a6520da86e272a609bc7fab',
|
12
|
+
api_key: 'apikey',
|
13
|
+
v: '1.0'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "builds complex options" do
|
18
|
+
subject.options([
|
19
|
+
Imagga::Image.new(url: 'http://image1', id: '333'),
|
20
|
+
Imagga::Image.new(url: 'http://image2')
|
21
|
+
], extract_overall_colors: true, extract_object_colors: false).should == {
|
22
|
+
urls: 'http://image1,http://image2',
|
23
|
+
ids: '333,0',
|
24
|
+
method: 'imagga.colorsearch.extract',
|
25
|
+
extract_overall_colors: 1,
|
26
|
+
extract_object_colors: 0,
|
27
|
+
sig: 'd66a0e3409ed08878ce7efae2827de87',
|
28
|
+
api_key: 'apikey',
|
29
|
+
v: '1.0'
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#build_urls" do
|
35
|
+
it "builds string of urls based on single image url string" do
|
36
|
+
subject.build_urls('http://image').should == 'http://image'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "builds string of urls based on image url string arrays" do
|
40
|
+
subject.build_urls(['http://image1', 'http://image2']).should == 'http://image1,http://image2'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "builds string of urls based on single image object" do
|
44
|
+
subject.build_urls(Imagga::Image.new(url: 'http://image')).should == 'http://image'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "builds string of urls based on image object array" do
|
48
|
+
subject.build_urls([
|
49
|
+
Imagga::Image.new(url: 'http://image1'),
|
50
|
+
Imagga::Image.new(url: 'http://image2')]).should == 'http://image1,http://image2'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#build_ids" do
|
55
|
+
it "returns 0 based on single image url string" do
|
56
|
+
subject.build_ids('http://image').should == nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns array of 0-s given image url string arrays" do
|
60
|
+
subject.build_ids(['http://image1', 'http://image2']).should == nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "builds string of ids based on single image object" do
|
64
|
+
subject.build_ids(Imagga::Image.new(url: 'http://image', id: '123')).should == '123'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "builds string of ids based on image object array" do
|
68
|
+
subject.build_ids([
|
69
|
+
Imagga::Image.new(url: 'http://image1', id: '123'),
|
70
|
+
Imagga::Image.new(url: 'http://image2')]).should == '123,0'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ImageColor do
|
4
|
+
|
5
|
+
let(:init_hash) { {
|
6
|
+
"percent" => '19.29',
|
7
|
+
"r" => '174', "g" => '180', "b" => '187',
|
8
|
+
"html_code" => "#aeb4bb",
|
9
|
+
"closest_palette_color" => "frost",
|
10
|
+
"closest_palette_color_parent" => "light grey",
|
11
|
+
"closest_palette_distance" => 2.03931376316
|
12
|
+
} }
|
13
|
+
|
14
|
+
describe "initialized by hash" do
|
15
|
+
subject { described_class.new(init_hash) }
|
16
|
+
|
17
|
+
it "has percent" do
|
18
|
+
subject.percent.should == 19.29
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has r" do
|
22
|
+
subject.r.should == 174
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has g" do
|
26
|
+
subject.g.should == 180
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has b" do
|
30
|
+
subject.b.should == 187
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has html_code" do
|
34
|
+
subject.html_code.should == '#aeb4bb'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has closest palette color" do
|
38
|
+
subject.closest_palette_color.should == 'frost'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has closest parent palette color" do
|
42
|
+
subject.closest_palette_color_parent.should == 'light grey'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has closest palette distance" do
|
46
|
+
subject.closest_palette_distance.should == 2.03931376316
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "initialized by hash with not supported attributes" do
|
51
|
+
subject { described_class.new(a: 'b') }
|
52
|
+
|
53
|
+
it "ignores not supported attributes" do
|
54
|
+
expect { subject.a }.to raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::ImageInfo do
|
4
|
+
|
5
|
+
let(:init_hash) { {
|
6
|
+
"url" => 'http://image',
|
7
|
+
"info" => {
|
8
|
+
"image_colors" => [ { "html_code" => "#676262", } ],
|
9
|
+
"foreground_colors" => [ { "html_code" => "#c7322b", } ],
|
10
|
+
"background_colors" => [ { "html_code" => "#676161", } ],
|
11
|
+
"object_percentage" => 17.99,
|
12
|
+
"color_variance" => "37",
|
13
|
+
"image_packed" => nil,
|
14
|
+
"foreground_packed" => nil,
|
15
|
+
"background_packed" => nil
|
16
|
+
}
|
17
|
+
} }
|
18
|
+
subject { described_class.new(init_hash) }
|
19
|
+
|
20
|
+
describe "initialized by hash" do
|
21
|
+
|
22
|
+
it "has url" do
|
23
|
+
subject.url.should == 'http://image'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "has image colors" do
|
27
|
+
subject.image_colors.should have(1).items
|
28
|
+
subject.image_colors.first.html_code.should == '#676262'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has foreground colors" do
|
32
|
+
subject.foreground_colors.should have(1).items
|
33
|
+
subject.foreground_colors.first.html_code.should == '#c7322b'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has background colors" do
|
37
|
+
subject.background_colors.should have(1).items
|
38
|
+
subject.background_colors.first.html_code.should == '#676161'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has object percentage" do
|
42
|
+
subject.object_percentage.should == 17.99
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has color variance" do
|
46
|
+
subject.color_variance.should == 37
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "initialized by hash with not supported attributes" do
|
51
|
+
subject { described_class.new(a: 'b') }
|
52
|
+
|
53
|
+
it "ignores not supported attributes" do
|
54
|
+
expect { subject.a }.to raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "initialied with empty color info" do
|
59
|
+
let(:init_hash) { {
|
60
|
+
"url" => 'http://image',
|
61
|
+
"info" => {
|
62
|
+
"image_colors" => [],
|
63
|
+
"foreground_colors" => [],
|
64
|
+
"background_colors" => [],
|
65
|
+
}
|
66
|
+
} }
|
67
|
+
|
68
|
+
it "initializes color infos as empty arrays" do
|
69
|
+
subject.image_colors.should be_empty
|
70
|
+
subject.foreground_colors.should be_empty
|
71
|
+
subject.background_colors.should be_empty
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "initialied with missing color info" do
|
76
|
+
let(:init_hash) { {
|
77
|
+
"url" => 'http://image',
|
78
|
+
"info" => {}
|
79
|
+
} }
|
80
|
+
|
81
|
+
it "does not initialize color infos" do
|
82
|
+
subject.image_colors.should be_nil
|
83
|
+
subject.foreground_colors.should be_nil
|
84
|
+
subject.background_colors.should be_nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::Image do
|
4
|
+
subject { described_class.new(url: 'http://', id: '1234') }
|
5
|
+
|
6
|
+
it "has id" do
|
7
|
+
subject.id.should == '1234'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has url" do
|
11
|
+
subject.url.should == 'http://'
|
12
|
+
end
|
13
|
+
|
14
|
+
context "without url" do
|
15
|
+
it "throws ArgumentError" do
|
16
|
+
expect{ described_class.new(id: '1234') }.to raise_error(ArgumentError, 'url is missing')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "without id" do
|
21
|
+
it "assigns id as 0" do
|
22
|
+
described_class.new(url: 'http://').id.should == 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::RankResultBuilder do
|
4
|
+
let(:result) { {
|
5
|
+
'rank_similarity' => [
|
6
|
+
{
|
7
|
+
"id" => 8774077,
|
8
|
+
"dist" => 2597.38299
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"id" => 9085916,
|
12
|
+
"dist" => 2681.33259
|
13
|
+
}
|
14
|
+
]
|
15
|
+
} }
|
16
|
+
|
17
|
+
subject { described_class.new }
|
18
|
+
|
19
|
+
describe '#build' do
|
20
|
+
it "builds result" do
|
21
|
+
subject.build_from(result).size.should == 2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Imagga::RankSimilarity do
|
4
|
+
|
5
|
+
let(:init_hash) { {
|
6
|
+
"id" => 8774077,
|
7
|
+
"dist" => 2597.38299
|
8
|
+
} }
|
9
|
+
|
10
|
+
describe "initialized by hash" do
|
11
|
+
subject { described_class.new(init_hash) }
|
12
|
+
|
13
|
+
it "has id" do
|
14
|
+
subject.id.should == 8774077
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has dist" do
|
18
|
+
subject.dist.should == 2597.38299
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# todo
|
23
|
+
describe "initialized by hash with not supported attributes" do
|
24
|
+
subject { described_class.new(a: 'b') }
|
25
|
+
|
26
|
+
it "ignores not supported attributes" do
|
27
|
+
expect { subject.a }.to raise_error
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rspec/autorun'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.require(:default, :development)
|
5
|
+
|
6
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
7
|
+
# in spec/support/ and its subdirectories.
|
8
|
+
Dir["spec/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: imagga
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mart Karu
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.10'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.10'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.7'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.7'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.12'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.12'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: fakeweb
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Ruby client for accessing Imagga API
|
95
|
+
email:
|
96
|
+
- karu@metal.ee
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .rspec
|
103
|
+
- .travis.yml
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- imagga.gemspec
|
109
|
+
- lib/imagga.rb
|
110
|
+
- lib/imagga/client.rb
|
111
|
+
- lib/imagga/exceptions.rb
|
112
|
+
- lib/imagga/extract_options.rb
|
113
|
+
- lib/imagga/extract_result_builder.rb
|
114
|
+
- lib/imagga/image.rb
|
115
|
+
- lib/imagga/rank_result_builder.rb
|
116
|
+
- lib/imagga/version.rb
|
117
|
+
- spec/lib/client_spec.rb
|
118
|
+
- spec/lib/extract_result_builder_spec.rb
|
119
|
+
- spec/lib/extraction_options_spec.rb
|
120
|
+
- spec/lib/image_color_spec.rb
|
121
|
+
- spec/lib/image_info_spec.rb
|
122
|
+
- spec/lib/image_spec.rb
|
123
|
+
- spec/lib/rank_result_builder_spec.rb
|
124
|
+
- spec/lib/rank_similarity_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
homepage: ''
|
127
|
+
licenses: []
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
hash: 440675985594337981
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
hash: 440675985594337981
|
150
|
+
requirements: []
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 1.8.25
|
153
|
+
signing_key:
|
154
|
+
specification_version: 3
|
155
|
+
summary: Ruby client for accessing Imagga API
|
156
|
+
test_files:
|
157
|
+
- spec/lib/client_spec.rb
|
158
|
+
- spec/lib/extract_result_builder_spec.rb
|
159
|
+
- spec/lib/extraction_options_spec.rb
|
160
|
+
- spec/lib/image_color_spec.rb
|
161
|
+
- spec/lib/image_info_spec.rb
|
162
|
+
- spec/lib/image_spec.rb
|
163
|
+
- spec/lib/rank_result_builder_spec.rb
|
164
|
+
- spec/lib/rank_similarity_spec.rb
|
165
|
+
- spec/spec_helper.rb
|