gcloud 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,245 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Gcloud
17
+ module Vision
18
+ class Annotation
19
+ ##
20
+ # # Properties
21
+ #
22
+ # A set of properties about an image, such as the image's dominant colors.
23
+ #
24
+ # See {Gcloud::Vision::Image#properties}.
25
+ #
26
+ # @example
27
+ # require "gcloud"
28
+ #
29
+ # gcloud = Gcloud.new
30
+ # vision = gcloud.vision
31
+ #
32
+ # image = vision.image "path/to/logo.jpg"
33
+ #
34
+ # properties = image.properties
35
+ # properties.colors.count #=> 10
36
+ #
37
+ class Properties
38
+ ##
39
+ # @private The ImageProperties Google API Client object.
40
+ attr_accessor :gapi
41
+
42
+ ##
43
+ # @private Creates a new Properties instance.
44
+ def initialize
45
+ @gapi = {}
46
+ end
47
+
48
+ ##
49
+ # The image's dominant colors, including their corresponding scores.
50
+ #
51
+ # @return [Array<Color>] An array of the image's dominant colors.
52
+ #
53
+ def colors
54
+ return [] unless @gapi["dominantColors"]
55
+ @colors ||= Array(@gapi["dominantColors"]["colors"]).map do |c|
56
+ Color.from_gapi c
57
+ end
58
+ end
59
+
60
+ ##
61
+ # Returns the object's property values as an array.
62
+ #
63
+ # @return [Array]
64
+ #
65
+ def to_a
66
+ to_ary
67
+ end
68
+
69
+ ##
70
+ # Returns the object's property values as an array.
71
+ #
72
+ # @return [Array]
73
+ #
74
+ def to_ary
75
+ colors.map(&:rgb)
76
+ end
77
+
78
+ ##
79
+ # Deeply converts object to a hash. All keys will be symbolized.
80
+ #
81
+ # @return [Hash]
82
+ #
83
+ def to_h
84
+ to_hash
85
+ end
86
+
87
+ ##
88
+ # Deeply converts object to a hash. All keys will be symbolized.
89
+ #
90
+ # @return [Hash]
91
+ #
92
+ def to_hash
93
+ { colors: colors.map(&:to_h) }
94
+ end
95
+
96
+ # @private
97
+ def to_s
98
+ "(colors: #{colors.count})"
99
+ end
100
+
101
+ # @private
102
+ def inspect
103
+ "#<Properties #{self}>"
104
+ end
105
+
106
+ ##
107
+ # @private New Annotation::Properties from a Google API Client object.
108
+ def self.from_gapi gapi
109
+ new.tap { |f| f.instance_variable_set :@gapi, gapi }
110
+ end
111
+
112
+ ##
113
+ # # Color
114
+ #
115
+ # Color information consisting of RGB channels, score, and fraction of
116
+ # image the color occupies in the image.
117
+ #
118
+ # @example
119
+ # require "gcloud"
120
+ #
121
+ # gcloud = Gcloud.new
122
+ # vision = gcloud.vision
123
+ #
124
+ # image = vision.image "path/to/logo.jpg"
125
+ # properties = image.properties
126
+ #
127
+ # color = properties.colors.first
128
+ # color.red #=> 247.0
129
+ # color.green #=> 236.0
130
+ # color.blue #=> 20.0
131
+ # color.rgb #=> "f7ec14"
132
+ # color.alpha #=> 1.0
133
+ # color.score #=> 0.20301804
134
+ # color.pixel_fraction #=> 0.0072649573
135
+ #
136
+ class Color
137
+ ##
138
+ # @private The ColorInfo Google API Client object.
139
+ attr_accessor :gapi
140
+
141
+ ##
142
+ # @private Creates a new Color instance.
143
+ def initialize
144
+ @gapi = {}
145
+ end
146
+
147
+ ##
148
+ # The amount of red in the color.
149
+ #
150
+ # @return [Float] A value in the interval [0, 255].
151
+ #
152
+ def red
153
+ @gapi["color"]["red"]
154
+ end
155
+
156
+ ##
157
+ # The amount of green in the color.
158
+ #
159
+ # @return [Float] A value in the interval [0, 255].
160
+ #
161
+ def green
162
+ @gapi["color"]["green"]
163
+ end
164
+
165
+ ##
166
+ # The amount of blue in the color.
167
+ #
168
+ # @return [Float] A value in the interval [0, 255].
169
+ #
170
+ def blue
171
+ @gapi["color"]["blue"]
172
+ end
173
+
174
+ ##
175
+ # The amount this color that should be applied to the pixel. A value
176
+ # of 1.0 corresponds to a solid color, whereas a value of 0.0
177
+ # corresponds to a completely transparent color.
178
+ #
179
+ # @return [Float] A value in the range [0, 1].
180
+ #
181
+ def alpha
182
+ @gapi["color"]["alpha"] || 1.0
183
+ end
184
+
185
+ def rgb
186
+ red.to_i.to_s(16).rjust(2, "0") +
187
+ green.to_i.to_s(16).rjust(2, "0") +
188
+ blue.to_i.to_s(16).rjust(2, "0")
189
+ end
190
+
191
+ ##
192
+ # Image-specific score for this color.
193
+ #
194
+ # @return [Float] A value in the range [0, 1].
195
+ #
196
+ def score
197
+ @gapi["score"]
198
+ end
199
+
200
+ ##
201
+ # Stores the fraction of pixels the color occupies in the image.
202
+ #
203
+ # @return [Float] A value in the range [0, 1].
204
+ #
205
+ def pixel_fraction
206
+ @gapi["pixelFraction"]
207
+ end
208
+
209
+ ##
210
+ # Converts object to a hash. All keys will be symbolized.
211
+ #
212
+ # @return [Hash]
213
+ #
214
+ def to_h
215
+ to_hash
216
+ end
217
+
218
+ ##
219
+ # Converts object to a hash. All keys will be symbolized.
220
+ #
221
+ # @return [Hash]
222
+ #
223
+ def to_hash
224
+ { red: red, green: green, blue: blue, alpha: alpha, rgb: rgb,
225
+ score: score, pixel_fraction: pixel_fraction }
226
+ end
227
+
228
+ def to_s
229
+ "(colors: #{rgb})"
230
+ end
231
+
232
+ def inspect
233
+ "#<Color #{self}>"
234
+ end
235
+
236
+ ##
237
+ # @private New Annotation::Properties from a Google API Client object.
238
+ def self.from_gapi gapi
239
+ new.tap { |f| f.instance_variable_set :@gapi, gapi }
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,161 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "gcloud/vision/annotation/vertex"
17
+
18
+ module Gcloud
19
+ module Vision
20
+ class Annotation
21
+ ##
22
+ # # SafeSearch
23
+ #
24
+ # A set of features pertaining to the image, computed by various computer
25
+ # vision methods over safe-search verticals (for example, adult, spoof,
26
+ # medical, violence).
27
+ #
28
+ # @example
29
+ # require "gcloud"
30
+ #
31
+ # gcloud = Gcloud.new
32
+ # vision = gcloud.vision
33
+ #
34
+ # image = vision.image "path/to/face.jpg"
35
+ #
36
+ # safe_search = image.safe_search
37
+ # safe_search.spoof? #=> false
38
+ # safe_search.spoof #=> "VERY_UNLIKELY"
39
+ #
40
+ class SafeSearch
41
+ POSITIVE_RATINGS = %w(POSSIBLE LIKELY VERY_LIKELY)
42
+
43
+ ##
44
+ # @private The SafeSearchAnnotation Google API Client object.
45
+ attr_accessor :gapi
46
+
47
+ ##
48
+ # @private Creates a new SafeSearch instance.
49
+ def initialize
50
+ @gapi = {}
51
+ end
52
+
53
+ ##
54
+ # Adult likelihood rating. Possible values are `VERY_UNLIKELY`,
55
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
56
+ def adult
57
+ @gapi["adult"]
58
+ end
59
+
60
+ ##
61
+ # Adult likelihood. Returns `true` if {#adult} is `POSSIBLE`, `LIKELY`,
62
+ # or `VERY_LIKELY`.
63
+ #
64
+ # @return [Boolean]
65
+ #
66
+ def adult?
67
+ POSITIVE_RATINGS.include? adult
68
+ end
69
+
70
+ ##
71
+ # Spoof likelihood rating. Possible values are `VERY_UNLIKELY`,
72
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
73
+ def spoof
74
+ @gapi["spoof"]
75
+ end
76
+
77
+ ##
78
+ # Spoof likelihood. Returns `true` if {#spoof} is `POSSIBLE`, `LIKELY`,
79
+ # or `VERY_LIKELY`.
80
+ #
81
+ # @return [Boolean]
82
+ #
83
+ def spoof?
84
+ POSITIVE_RATINGS.include? spoof
85
+ end
86
+
87
+ ##
88
+ # Medical likelihood rating. Possible values are `VERY_UNLIKELY`,
89
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
90
+ def medical
91
+ @gapi["medical"]
92
+ end
93
+
94
+ ##
95
+ # Medical likelihood. Returns `true` if {#medical} is `POSSIBLE`,
96
+ # `LIKELY`, or `VERY_LIKELY`.
97
+ #
98
+ # @return [Boolean]
99
+ #
100
+ def medical?
101
+ POSITIVE_RATINGS.include? medical
102
+ end
103
+
104
+ ##
105
+ # Violence likelihood rating. Possible values are `VERY_UNLIKELY`,
106
+ # `UNLIKELY`, `POSSIBLE`, `LIKELY`, and `VERY_LIKELY`.
107
+ def violence
108
+ @gapi["violence"]
109
+ end
110
+
111
+ ##
112
+ # Violence likelihood. Returns `true` if {#violence} is `POSSIBLE`,
113
+ # `LIKELY`, or `VERY_LIKELY`.
114
+ #
115
+ # @return [Boolean]
116
+ #
117
+ def violence?
118
+ POSITIVE_RATINGS.include? violence
119
+ end
120
+
121
+ ##
122
+ # Converts object to a hash. All keys will be symbolized.
123
+ #
124
+ # @return [Hash]
125
+ #
126
+ def to_h
127
+ to_hash
128
+ end
129
+
130
+ ##
131
+ # Converts object to a hash. All keys will be symbolized.
132
+ #
133
+ # @return [Hash]
134
+ #
135
+ def to_hash
136
+ { adult: adult?, spoof: spoof?, medical: medical?,
137
+ violence: violence? }
138
+ end
139
+
140
+ # @private
141
+ def to_s
142
+ tmplt = "(adult?: %s, spoof?: %s, medical?: %s, " \
143
+ "violence?: %s)"
144
+ format tmplt, adult?.inspect, spoof?.inspect, medical?.inspect,
145
+ violence?.inspect
146
+ end
147
+
148
+ # @private
149
+ def inspect
150
+ "#<SafeSearch #{self}>"
151
+ end
152
+
153
+ ##
154
+ # @private New Annotation::SafeSearch from a Google API Client object.
155
+ def self.from_gapi gapi
156
+ new.tap { |f| f.instance_variable_set :@gapi, gapi }
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,236 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "gcloud/vision/annotation/vertex"
17
+
18
+ module Gcloud
19
+ module Vision
20
+ class Annotation
21
+ ##
22
+ # # Text
23
+ #
24
+ # The result of text, or optical character recognition (OCR), detection.
25
+ #
26
+ # @example
27
+ # require "gcloud"
28
+ #
29
+ # gcloud = Gcloud.new
30
+ # vision = gcloud.vision
31
+ #
32
+ # image = vision.image "path/to/text.png"
33
+ #
34
+ # text = image.text
35
+ # text.locale #=> "en"
36
+ # text.words.count #=> 28
37
+ # text.text
38
+ # #=> "Google Cloud Client Library for Ruby an idiomatic, intuitive... "
39
+ #
40
+ class Text
41
+ ##
42
+ # @private The EntityAnnotation Google API Client object.
43
+ attr_accessor :gapi
44
+
45
+ ##
46
+ # @private Creates a new Text instance.
47
+ def initialize
48
+ @gapi = {}
49
+ @words = []
50
+ end
51
+
52
+ ##
53
+ # The text detected in an image.
54
+ #
55
+ # @return [String] The entire text including newline characters.
56
+ #
57
+ def text
58
+ @gapi["description"]
59
+ end
60
+
61
+ ##
62
+ # The language code detected for `text`.
63
+ #
64
+ # @return [String] The [ISO
65
+ # 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
66
+ # language code.
67
+ #
68
+ def locale
69
+ @gapi["locale"]
70
+ end
71
+
72
+ ##
73
+ # The bounds for the detected text in the image.
74
+ #
75
+ # @return [Array<Vertex>]
76
+ #
77
+ def bounds
78
+ return [] unless @gapi["boundingPoly"]
79
+ @bounds ||= Array(@gapi["boundingPoly"]["vertices"]).map do |v|
80
+ Vertex.from_gapi v
81
+ end
82
+ end
83
+
84
+ ##
85
+ # Each word in the detected text, with the bounds for each word.
86
+ #
87
+ # @return [Array<Word>]
88
+ #
89
+ def words
90
+ @words
91
+ end
92
+
93
+ ##
94
+ # Deeply converts object to a hash. All keys will be symbolized.
95
+ #
96
+ # @return [Hash]
97
+ #
98
+ def to_h
99
+ to_hash
100
+ end
101
+
102
+ ##
103
+ # Deeply converts object to a hash. All keys will be symbolized.
104
+ #
105
+ # @return [Hash]
106
+ #
107
+ def to_hash
108
+ { text: text, locale: locale, bounds: bounds.map(&:to_h),
109
+ words: words.map(&:to_h) }
110
+ end
111
+
112
+ # @private
113
+ def to_s
114
+ to_str
115
+ end
116
+
117
+ # @private
118
+ def to_str
119
+ text
120
+ end
121
+
122
+ # @private
123
+ def inspect
124
+ format "#<Text text: %s, locale: %s, bounds: %i, words: %i>",
125
+ text.inspect, locale.inspect, bounds.count, words.count
126
+ end
127
+
128
+ ##
129
+ # @private New Annotation::Text from an array of Google API Client
130
+ # objects.
131
+ def self.from_gapi gapi_list
132
+ text, *words = Array gapi_list
133
+ return nil if text.nil?
134
+ new.tap do |t|
135
+ t.instance_variable_set :@gapi, text
136
+ t.instance_variable_set :@words, words.map { |w| Word.from_gapi w }
137
+ end
138
+ end
139
+
140
+ ##
141
+ # # Word
142
+ #
143
+ # A word within a detected text (OCR). See {Text}.
144
+ #
145
+ # @example
146
+ # require "gcloud"
147
+ #
148
+ # gcloud = Gcloud.new
149
+ # vision = gcloud.vision
150
+ #
151
+ # image = vision.image "path/to/text.png"
152
+ # text = image.text
153
+ #
154
+ # words = text.words
155
+ # words.count #=> 28
156
+ #
157
+ # word = words.first
158
+ # word.text #=> "Google"
159
+ # word.bounds.count #=> 4
160
+ # word.bounds.first #=> #<Vertex (x: 13, y: 8)>
161
+ #
162
+ class Word
163
+ ##
164
+ # @private The EntityAnnotation Google API Client object.
165
+ attr_accessor :gapi
166
+
167
+ ##
168
+ # @private Creates a new Word instance.
169
+ def initialize
170
+ @gapi = {}
171
+ end
172
+
173
+ ##
174
+ # The text of the word.
175
+ #
176
+ # @return [String]
177
+ #
178
+ def text
179
+ @gapi["description"]
180
+ end
181
+
182
+ ##
183
+ # The bounds of the word within the detected text.
184
+ #
185
+ # @return [Array<Vertex>]
186
+ #
187
+ def bounds
188
+ return [] unless @gapi["boundingPoly"]
189
+ @bounds ||= Array(@gapi["boundingPoly"]["vertices"]).map do |v|
190
+ Vertex.from_gapi v
191
+ end
192
+ end
193
+
194
+ ##
195
+ # Deeply converts object to a hash. All keys will be symbolized.
196
+ #
197
+ # @return [Hash]
198
+ #
199
+ def to_h
200
+ to_hash
201
+ end
202
+
203
+ ##
204
+ # Deeply converts object to a hash. All keys will be symbolized.
205
+ #
206
+ # @return [Hash]
207
+ #
208
+ def to_hash
209
+ { text: text, bounds: bounds.map(&:to_h) }
210
+ end
211
+
212
+ # @private
213
+ def to_s
214
+ to_str
215
+ end
216
+
217
+ # @private
218
+ def to_str
219
+ text
220
+ end
221
+
222
+ # @private
223
+ def inspect
224
+ format "#<Word text: %s, bounds: %i>", text.inspect, bounds.count
225
+ end
226
+
227
+ ##
228
+ # @private New Annotation::Text::Word from a Google API Client object.
229
+ def self.from_gapi gapi
230
+ new.tap { |w| w.instance_variable_set :@gapi, gapi }
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end