featuredimage 0.9.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.
- data/lib/featuredimage/converter.rb +64 -0
- data/lib/featuredimage/finder.rb +187 -0
- data/lib/featuredimage.rb +2 -0
- metadata +91 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'RMagick'
|
2
|
+
|
3
|
+
module FeaturedImage
|
4
|
+
class Converter
|
5
|
+
attr_accessor :width, :height, :opts
|
6
|
+
|
7
|
+
def self.convert(image, w, h, opts = {})
|
8
|
+
converter = Converter.new(w, h, opts)
|
9
|
+
converter.convert(image)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(width, height, opts = {})
|
13
|
+
@width, @height = width, height
|
14
|
+
|
15
|
+
# default convert options
|
16
|
+
@opts = {
|
17
|
+
:format => "JPG",
|
18
|
+
:quality => 60
|
19
|
+
}
|
20
|
+
@opts.merge!(opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def convert(image)
|
24
|
+
target_size = {w:@width, h:@height}
|
25
|
+
original_size = {w:image.columns, h:image.rows}
|
26
|
+
|
27
|
+
resized_size = get_resized_size(original_size, target_size)
|
28
|
+
resized_image = image.resize(resized_size[:w], resized_size[:h])
|
29
|
+
|
30
|
+
offset = get_offset(target_size, resized_size)
|
31
|
+
cropped_image = resized_image.crop(offset[:x], offset[:y], target_size[:w], target_size[:h])
|
32
|
+
|
33
|
+
image_to_blob(cropped_image)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def get_resized_size(src, dst)
|
38
|
+
w_ratio = dst[:w].to_f / src[:w]
|
39
|
+
h_ratio = dst[:h].to_f / src[:h]
|
40
|
+
ratio = 0
|
41
|
+
if w_ratio > h_ratio
|
42
|
+
ratio = w_ratio
|
43
|
+
else
|
44
|
+
ratio = h_ratio
|
45
|
+
end
|
46
|
+
{w:(src[:w] * ratio).to_i, h:(src[:h] * ratio).to_i}
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_offset(target_size, resized_size)
|
50
|
+
offset_x = (resized_size[:w] - target_size[:w]) / 2
|
51
|
+
offset_y = (resized_size[:h] - target_size[:h]) / 2
|
52
|
+
{:x => offset_x, :y => offset_y}
|
53
|
+
end
|
54
|
+
|
55
|
+
def image_to_blob(image)
|
56
|
+
opts = @opts
|
57
|
+
image.to_blob{
|
58
|
+
opts.each{|k, v|
|
59
|
+
self.send(k.to_s + '=', v)
|
60
|
+
}
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require "mechanize"
|
2
|
+
require "RMagick"
|
3
|
+
|
4
|
+
module FeaturedImage
|
5
|
+
class Finder
|
6
|
+
# Find first featured image that is matching criteria from web page.
|
7
|
+
# And return it as Magick::ImageList.
|
8
|
+
# If the featured image does not exist return nil.
|
9
|
+
def self.first(url, *args)
|
10
|
+
finder = Finder.new
|
11
|
+
cond = Criteria.new(*args)
|
12
|
+
finder.first(url, cond)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Find the biggest featured image that is matching criteria from web page.
|
16
|
+
# And return it as Magick::ImageList.
|
17
|
+
# If the featured image does not exist return nil.
|
18
|
+
def self.biggest(url, *args)
|
19
|
+
finder = Finder.new
|
20
|
+
cond = Criteria.new(*args)
|
21
|
+
finder.biggest(url, cond)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Find all featured images that are matching criteria from web page.
|
25
|
+
# And return them as Array of Magick::ImageList.
|
26
|
+
# If the featured image does not exist return empty Array.
|
27
|
+
def self.all(url, *args)
|
28
|
+
finder = Finder.new
|
29
|
+
cond = Criteria.new(*args)
|
30
|
+
finder.all(url, cond)
|
31
|
+
end
|
32
|
+
|
33
|
+
def first(url, cond)
|
34
|
+
agent = Mechanize.new
|
35
|
+
page = agent.get(url)
|
36
|
+
page.search("img").each{|elm|
|
37
|
+
src = elm.attributes["src"].value
|
38
|
+
begin
|
39
|
+
data = download_image(agent, src)
|
40
|
+
|
41
|
+
imagelist = Magick::ImageList.new
|
42
|
+
imagelist.from_blob(data)
|
43
|
+
|
44
|
+
size = Size.new(imagelist.columns, imagelist.rows)
|
45
|
+
if featured_image?(cond, size)
|
46
|
+
return imagelist
|
47
|
+
end
|
48
|
+
rescue Mechanize::ResponseCodeError
|
49
|
+
# ignore Mechanize::ResponseCodeError
|
50
|
+
end
|
51
|
+
}
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def biggest(url, cond)
|
56
|
+
agent = Mechanize.new
|
57
|
+
page = agent.get(url)
|
58
|
+
|
59
|
+
max_size = Size.new(0, 0)
|
60
|
+
max_imagelist = nil
|
61
|
+
|
62
|
+
page.search("img").each{|elm|
|
63
|
+
src = elm.attributes["src"].value
|
64
|
+
begin
|
65
|
+
data = download_image(agent, src)
|
66
|
+
|
67
|
+
imagelist = Magick::ImageList.new
|
68
|
+
imagelist.from_blob(data)
|
69
|
+
|
70
|
+
size = Size.new(imagelist.columns, imagelist.rows)
|
71
|
+
if featured_image?(cond, size)
|
72
|
+
if max_size < size
|
73
|
+
max_size = size
|
74
|
+
max_imagelist = imagelist
|
75
|
+
end
|
76
|
+
end
|
77
|
+
rescue Mechanize::ResponseCodeError
|
78
|
+
# ignore Mechanize::ResponseCodeError
|
79
|
+
end
|
80
|
+
}
|
81
|
+
|
82
|
+
max_imagelist
|
83
|
+
end
|
84
|
+
|
85
|
+
def all(url, cond)
|
86
|
+
agent = Mechanize.new
|
87
|
+
page = agent.get(url)
|
88
|
+
|
89
|
+
max_size = Size.new(0, 0)
|
90
|
+
max_imagelist = nil
|
91
|
+
|
92
|
+
results = []
|
93
|
+
page.search("img").each{|elm|
|
94
|
+
src = elm.attributes["src"].value
|
95
|
+
begin
|
96
|
+
data = download_image(agent, src)
|
97
|
+
|
98
|
+
imagelist = Magick::ImageList.new
|
99
|
+
imagelist.from_blob(data)
|
100
|
+
|
101
|
+
size = Size.new(imagelist.columns, imagelist.rows)
|
102
|
+
results << imagelist if featured_image?(cond, size)
|
103
|
+
rescue Mechanize::ResponseCodeError
|
104
|
+
# ignore Mechanize::ResponseCodeError
|
105
|
+
end
|
106
|
+
}
|
107
|
+
results
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
def download_image(agent, src)
|
112
|
+
agent.get(src).body
|
113
|
+
end
|
114
|
+
|
115
|
+
def featured_image?(cond, size)
|
116
|
+
cond.check(size)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class Criteria
|
121
|
+
attr_accessor :min_width, :max_width, :min_height, :max_height, :aspect_range
|
122
|
+
|
123
|
+
def initialize(*args)
|
124
|
+
# default criteria size 0x0 to 4096x4096
|
125
|
+
@min_width = 0
|
126
|
+
@max_width = 4096
|
127
|
+
@min_height = 0
|
128
|
+
@max_height = 4096
|
129
|
+
@aspect_range = 0..4096
|
130
|
+
|
131
|
+
case args.length
|
132
|
+
when 0
|
133
|
+
# default criteria
|
134
|
+
when 1
|
135
|
+
@aspect_range = args[0]
|
136
|
+
when 2
|
137
|
+
@min_width = args[0]
|
138
|
+
@min_height = args[1]
|
139
|
+
when 3
|
140
|
+
@min_width = args[0]
|
141
|
+
@min_height = args[1]
|
142
|
+
@aspect_range = args[2]
|
143
|
+
when 4
|
144
|
+
@min_width = args[0]
|
145
|
+
@max_width = args[1]
|
146
|
+
@min_height = args[2]
|
147
|
+
@max_height = args[3]
|
148
|
+
when 5
|
149
|
+
@min_width = args[0]
|
150
|
+
@max_width = args[1]
|
151
|
+
@min_height = args[2]
|
152
|
+
@max_height = args[3]
|
153
|
+
@aspect_range = args[4]
|
154
|
+
else
|
155
|
+
raise ArgumentError.new
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def check(size)
|
160
|
+
if @min_width < size.width and
|
161
|
+
size.width < @max_width and
|
162
|
+
@min_height < size.height and
|
163
|
+
size.height < @max_height and
|
164
|
+
@aspect_range.include?(size.aspect)
|
165
|
+
true
|
166
|
+
else
|
167
|
+
false
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class Size
|
173
|
+
attr_accessor :width, :height
|
174
|
+
|
175
|
+
def initialize(width, height)
|
176
|
+
@width, @height = width, height
|
177
|
+
end
|
178
|
+
|
179
|
+
def aspect
|
180
|
+
width.to_f / height.to_f # ;-)
|
181
|
+
end
|
182
|
+
|
183
|
+
def <(size)
|
184
|
+
@width * @height < size.width * size.height ? true : false
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: featuredimage
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- xmisao
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mechanize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
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'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rmagick
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
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: '0'
|
46
|
+
description: ! 'FeaturedImage is the finder that extract featured image from a web
|
47
|
+
page.
|
48
|
+
|
49
|
+
FeaturedImage::Finder accesses and analyses a web page using Mechanize, download
|
50
|
+
images which are referenced by IMG tag in HTML, and specify a featured image based
|
51
|
+
on size of image using RMagick.
|
52
|
+
|
53
|
+
Furthermore, FeaturedImage contains pretty good thumbnail generating function too.
|
54
|
+
FeaturedImage::Converter crops centered area of image, resizes, and convert to arbitrary
|
55
|
+
format automatically.
|
56
|
+
|
57
|
+
'
|
58
|
+
email: mail@xmisao.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/featuredimage.rb
|
64
|
+
- lib/featuredimage/finder.rb
|
65
|
+
- lib/featuredimage/converter.rb
|
66
|
+
homepage: https://github.com/xmisao/featuredimage
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 1.8.23
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: FeaturedImage is the finder that extract featured image from a web page.
|
91
|
+
test_files: []
|