gcloud 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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