paperclip-facecrop 0.0.6 → 0.1.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/README.md CHANGED
@@ -2,15 +2,30 @@ Paperclip::FaceCrop
2
2
  ====================
3
3
  `Paperclip::FaceCrop` is a [Paperclip][paperclip] processor that is aware of the faces found on the image
4
4
  so that they aren't cropped or aren't shown too small while generating the thumbnails.
5
- It uses OpenCV for the facial recognition
5
+ It can use the [OpenCV][opencv] library or the [Face.com][face_com] web service(or both at the same time) for the facial recognition.
6
6
 
7
7
  ![](https://github.com/dagi3d/paperclip-facecrop/raw/master/README_example.jpg)
8
8
 
9
9
  Requirements:
10
10
  -------------
11
+
12
+ ### OpenCV
13
+
14
+ If you want to use OpenCV on your own server, you need to install:
15
+
11
16
  - [OpenCV][opencv]
12
17
  - [OpenCV ruby binding][ruby-opencv]
13
18
 
19
+ In case you get the error message `/ext/opencv/cverror.cpp:143: error: ‘CV_GpuCufftCallError’ was not declared in this scope` while installing the ruby binding,
20
+ checkout the OpenCV_2.2 branch or just remove the line 143 from `/ext/opencv/cverror.cpp`
21
+
22
+
23
+ ### Face.com
24
+ - [rest-client][rest-client]
25
+
26
+ In order to use the Face.com service, you will also need to register in order to get your api key and api secret for your application.
27
+
28
+
14
29
  Installation:
15
30
  -------------
16
31
  - Add to your application `Gemfile`
@@ -21,39 +36,55 @@ Installation:
21
36
 
22
37
  bundle install
23
38
 
24
- - Write an initializer setting the path of the haarcascade filters(`initializers/paperclip.rb` for example):
25
39
 
26
- Paperclip::FaceCrop.classifiers = {
27
- :face => ["/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"]
40
+ - Write an initializer setting the detectors configuration (`initializers/paperclip.rb` for example):
41
+
42
+ ### OpenCV
43
+
44
+ Set the path of the haarcascade filters:
45
+
46
+ Paperclip::FaceCrop.detectors = {
47
+ 'OpenCV' => {
48
+ :face => %w(/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml)
49
+ }
28
50
  }
51
+
52
+
29
53
 
30
- You can use more than one filter to try more accurate searches:
54
+ You can use more than one filter to try more accurate searches:
31
55
 
32
- Paperclip::FaceCrop.classifiers = {
33
- :face => [
34
- "/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml",
35
- "/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml",
36
- "/usr/local/share/opencv/haarcascades/haarcascade_profileface.xml"
37
- ]
56
+ Paperclip::FaceCrop.detectors = {
57
+ 'OpenCV' => {
58
+ :face => %w(/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml
59
+ /usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml
60
+ /usr/local/share/opencv/haarcascades/haarcascade_profileface.xml)
61
+ }
38
62
  }
39
63
 
40
- In order to try to avoid some false positives, you can also specify other classifiers to detect other parts of the face. In that case,
41
- only the found areas that contain parts like a mouth, an eye or a nose will be considered a face:
64
+
65
+
66
+ In order to try to avoid some false positives, you can also specify other classifiers to detect other parts of the face. In that case,
67
+ only the found areas that contain parts like a mouth, an eye or a nose will be considered a face:
42
68
 
43
- Paperclip::FaceCrop.classifiers = {
44
- :face => [
45
- "/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml",
46
- "/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml",
47
- "/usr/local/share/opencv/haarcascades/haarcascade_profileface.xml"
48
- ],
49
- :parts => [
50
- "/usr/local/share/opencv/haarcascades/haarcascade_mcs_nose.xml",
51
- "/usr/local/share/opencv/haarcascades/haarcascade_mcs_lefteye.xml",
52
- "/usr/local/share/opencv/haarcascades/haarcascade_mcs_righteye.xml"
53
- ]
69
+ Paperclip::FaceCrop.detectors = {
70
+ 'OpenCV' => {
71
+ :face => %w(/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml
72
+ /usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml
73
+ /usr/local/share/opencv/haarcascades/haarcascade_profileface.xml),
74
+
75
+ :parts => %w(/usr/local/share/opencv/haarcascades/haarcascade_mcs_nose.xml
76
+ /usr/local/share/opencv/haarcascades/haarcascade_mcs_lefteye.xml
77
+ /usr/local/share/opencv/haarcascades/haarcascade_mcs_righteye.xml)
78
+ }
54
79
  }
80
+
55
81
 
56
-
82
+ ### Face.com
83
+
84
+ Paperclip::FaceCrop.detectors = {
85
+ 'FaceCom' => { :api_key => "<YOUR API KEY>", :api_secret => "<YOUR API SECRET>"}
86
+ }
87
+
57
88
 
58
89
  Usage:
59
90
  ------
@@ -71,15 +102,19 @@ In case no faces were found, it will behave simply as the `Paperclip::Thumbnail`
71
102
 
72
103
  You can also set the debug mode to draw on the image the detected regions:
73
104
 
74
- Paperclip::FaceCrop.debug = (Rails.env == 'development')
105
+ Paperclip::FaceCrop.debug = Rails.env.development?
75
106
 
76
107
  ![](https://github.com/dagi3d/paperclip-facecrop/raw/master/README_example_b.jpg)
77
108
 
109
+ Each detector will draw the found regions in different colors(Face.com detector in red and OpenCV in green)
110
+
78
111
  Credits:
79
112
  --------
80
113
  Copyright (c) 2011 Borja Martín Sánchez de Vivar <borjamREMOVETHIS@dagi3d.net> - <http://dagi3d.net>, released under the MIT license
81
114
  The photo used as example belongs to [Jesper Rønn-Jensen](http://www.flickr.com/photos/jesper/)
82
115
 
116
+ [face_com]: http://face.com
117
+ [rest-client]: https://rubygems.org/gems/rest-client
83
118
  [paperclip]: https://github.com/thoughtbot/paperclip
84
119
  [opencv]: http://opencv.willowgarage.com/
85
120
  [ruby-opencv]: https://github.com/ser1zw/ruby-opencv
data/README_example_b.jpg CHANGED
Binary file
@@ -0,0 +1,27 @@
1
+ require 'rest_client'
2
+
3
+ class FaceCrop::Detector::FaceCom < FaceCrop::Detector::Base
4
+ URL = "http://api.face.com/faces/detect.json"
5
+
6
+ def detect_faces(file)
7
+ query = @options.to_query
8
+ url = "#{URL}?#{query}"
9
+
10
+ response = RestClient.post url, :file => File.new(file)
11
+ response = JSON.parse(response)
12
+
13
+ photo = response['photos'].first
14
+ photo['tags'].map do |tag|
15
+ # values are returned as percentual values
16
+ x = (photo['width'] * (tag['center']['x'] / 100.0)).to_i
17
+ y = (photo['height'] * (tag['center']['y'] / 100.0)).to_i
18
+ w = (photo['width'] * (tag['width'] / 100)).to_i
19
+ h = (photo['height'] * (tag['height'] / 100)).to_i
20
+
21
+ region = FaceCrop::Detector::Region.new(x, y, w, h)
22
+ region.color = "green"
23
+ region
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,44 @@
1
+ require 'opencv'
2
+ require File.expand_path('../opencv_ext', __FILE__)
3
+
4
+ class FaceCrop::Detector::OpenCV < FaceCrop::Detector::Base
5
+
6
+ def detect_faces(file)
7
+
8
+ image = OpenCV::IplImage.load(file, 1)
9
+
10
+ faces_regions = detect_regions(image, @options[:face])
11
+
12
+ #Paperclip::FaceCrop.classifiers[:nose]
13
+ unless @options[:parts].nil?
14
+ faces_parts_regions = detect_regions(image, @options[:parts])
15
+
16
+ faces_regions.reject! do |face_region|
17
+ region = faces_parts_regions.detect do |part_region|
18
+ # part of a face can't be bigger than the face itself
19
+ face_region.collide?(part_region) && face_region > part_region
20
+ end
21
+
22
+ region.nil?
23
+ end
24
+ end
25
+
26
+ faces_regions
27
+
28
+ end
29
+
30
+ private
31
+ def detect_regions(image, classifiers, color = OpenCV::CvColor::Blue)
32
+ regions = []
33
+
34
+ classifiers.each do |classifier|
35
+ detector = OpenCV::CvHaarClassifierCascade::load(classifier)
36
+ detector.detect_objects(image) do |region|
37
+ region.color = "red"
38
+ regions << region
39
+ end
40
+ end
41
+
42
+ regions
43
+ end
44
+ end
@@ -1,7 +1,7 @@
1
- require 'opencv'
2
-
3
1
  class OpenCV::CvAvgComp
4
2
 
3
+ attr_accessor :color
4
+
5
5
  # collide?
6
6
  #
7
7
  def collide?(comp)
data/lib/face_crop.rb ADDED
@@ -0,0 +1,86 @@
1
+ module FaceCrop
2
+
3
+ # Detector
4
+ #
5
+ module Detector
6
+
7
+ autoload :FaceCom, File.expand_path('../detectors/face_com', __FILE__)
8
+ autoload :OpenCV, File.expand_path('../detectors/opencv', __FILE__)
9
+
10
+ # Base
11
+ #
12
+ class Base
13
+
14
+ # initialize
15
+ #
16
+ def initialize(options)
17
+ @options = options
18
+ end
19
+
20
+ # detect
21
+ #
22
+ def detect(file)
23
+ key = "#{self.class}#{file}"
24
+ regions = FaceCrop::Detector::Cache[key]
25
+ return regions unless regions.nil?
26
+
27
+ regions = detect_faces(file)
28
+ FaceCrop::Detector::Cache[key] = regions
29
+ regions
30
+ end
31
+
32
+ end
33
+
34
+ class Cache
35
+ @@cache = {}
36
+
37
+ def self.[]=(key, faces)
38
+ @@cache[key] = faces
39
+ end
40
+
41
+ def self.[](key)
42
+ @@cache[key]
43
+ end
44
+
45
+ def self.clear
46
+ @@cache = {}
47
+ end
48
+ end
49
+
50
+ # Region
51
+ #
52
+ class Region
53
+ attr_accessor :center
54
+ attr_accessor :width
55
+ attr_accessor :height
56
+ attr_accessor :color
57
+
58
+ def initialize(x, y, width, height)
59
+ @width, @height = width, height
60
+ @center = Point.new(x, y)
61
+ end
62
+
63
+ def top_left
64
+ @top_left ||= Point.new(@center.x - (width / 2), @center.y - (height / 2))
65
+ end
66
+
67
+ def bottom_right
68
+ @bottom_right ||= Point.new(@center.x + (width / 2), @center.y + (height / 2))
69
+ end
70
+
71
+ def to_s
72
+ "#{center.x},#{center.y}-#{width}x#{height}"
73
+ end
74
+ end
75
+
76
+ # Point
77
+ #
78
+ class Point
79
+ attr_accessor :x
80
+ attr_accessor :y
81
+ def initialize(x,y)
82
+ @x, @y = x, y
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,149 +1,2 @@
1
- require File.join(File.dirname(__FILE__), 'opencv_ext')
2
-
3
- module Paperclip
4
- class FaceCrop < Paperclip::Thumbnail
5
-
6
- @@debug = false
7
-
8
- cattr_accessor :classifiers
9
- cattr_accessor :debug
10
-
11
- def initialize(file, options = {}, attachment = nil)
12
- super(file, options, attachment)
13
-
14
- faces_regions = []
15
- faces_parts_regions = []
16
-
17
- raise "No classifiers were defined" if self.classifiers.nil?
18
-
19
- image = OpenCV::IplImage.load(file.path, 1)
20
-
21
- faces_regions = detect_regions(image, self.classifiers[:face])
22
-
23
- #Paperclip::FaceCrop.classifiers[:nose]
24
- unless self.classifiers[:parts].nil?
25
- faces_parts_regions = detect_regions(image, self.classifiers[:parts], OpenCV::CvColor::Red)
26
-
27
- faces_regions.reject! do |face_region|
28
- region = faces_parts_regions.detect do |part_region|
29
- # part of a face can't be bigger than the face itself
30
- face_region.collide?(part_region) && face_region > part_region
31
- end
32
-
33
- region.nil?
34
- end
35
- end
36
-
37
- x_coords = []
38
- y_coords = []
39
- widths = []
40
- heights = []
41
-
42
- faces_regions.each do |region|
43
- x_coords << region.top_left.x << region.bottom_right.x
44
- y_coords << region.top_left.y << region.bottom_right.y
45
- widths << region.width
46
- heights << region.height
47
- end
48
-
49
- @has_faces = faces_regions.size > 0
50
-
51
- if @has_faces
52
- @top_left_x = x_coords.min
53
- @top_left_y = y_coords.min
54
- @bottom_right_x = x_coords.max
55
- @bottom_right_y = y_coords.max
56
-
57
- # average faces areas
58
- average_face_width = widths.sum / widths.size
59
- average_face_height = heights.sum / heights.size
60
-
61
- # calculating the surrounding margin of the area that covers all the found faces
62
- #
63
-
64
- # new width
65
- @top_left_x -= average_face_width / 2
66
- @bottom_right_x += average_face_width / 2
67
-
68
- # new height
69
- @top_left_y -= average_face_height / 2
70
- @bottom_right_y += average_face_height / 1.6
71
-
72
- calculate_bounds
73
-
74
- # if the new area is smaller than the target geometry, it's scaled so the final image isn't resampled
75
- #
76
- if @faces_width < @target_geometry.width
77
- delta_width = (@target_geometry.width - @faces_width) / 2
78
- @top_left_x -= delta_width
79
- @bottom_right_x += delta_width
80
- calculate_bounds
81
- end
82
-
83
- #raise (@target_geometry.height > 0 and @faces_height < @target_geometry.height).to_s
84
-
85
- if (@target_geometry.height > 0 and @faces_height < @target_geometry.height)
86
- delta_height = (@target_geometry.height - @faces_height) / 2
87
- @top_left_y -= delta_height
88
- @bottom_right_y += delta_height
89
- calculate_bounds
90
- end
91
-
92
- @faces_height = @faces_width if @target_geometry.height == 0
93
-
94
- @current_geometry = Paperclip::Geometry.new(@faces_width, @faces_height)
95
- end
96
-
97
- end
98
-
99
-
100
- def transformation_command
101
- return super unless @has_faces
102
-
103
- scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
104
- faces_crop = "%dx%d+%d+%d" % [@faces_width, @faces_height, @top_left_x, @top_left_y]
105
-
106
- trans = []
107
- trans << "-crop" << %["#{faces_crop}"] << "+repage"
108
- trans << "-resize" << %["#{scale}"] unless scale.nil? || scale.empty?
109
- trans << "-crop" << %["#{crop}"] << "+repage" if crop
110
- trans
111
- end
112
-
113
- private
114
-
115
- # calculate_bounds
116
- #
117
- def calculate_bounds
118
- @top_left_x = 0 if @top_left_x < 0
119
- @bottom_right_x = @current_geometry.width if @bottom_right_x > @current_geometry.width
120
-
121
- @top_left_y = 0 if @top_left_y < 0
122
- @bottom_right_y = @current_geometry.height if @bottom_right_y > @current_geometry.height
123
-
124
- @faces_width = @bottom_right_x - @top_left_x
125
- @faces_height = @bottom_right_y - @top_left_y
126
- end
127
-
128
- # detect_regions
129
- #
130
- def detect_regions(image, classifiers, color = OpenCV::CvColor::Blue)
131
- regions = []
132
-
133
- classifiers.each do |classifier|
134
- detector = OpenCV::CvHaarClassifierCascade::load(classifier)
135
- detector.detect_objects(image) do |region|
136
- regions << region
137
- image.rectangle!(region.top_left, region.bottom_right, :color => color) if self.debug
138
- end
139
- end
140
-
141
- if self.debug
142
- image.save_image(@file.path)
143
- Rails.logger.info(regions)
144
- end
145
-
146
- regions
147
- end
148
- end
149
- end
1
+ require File.expand_path('../processor', __FILE__)
2
+ require File.expand_path('../railtie', __FILE__)
data/lib/processor.rb ADDED
@@ -0,0 +1,143 @@
1
+ require File.expand_path('../face_crop', __FILE__)
2
+
3
+ module Paperclip
4
+ class FaceCrop < Paperclip::Thumbnail
5
+
6
+ @@debug = false
7
+
8
+ #cattr_accessor :classifiers
9
+ cattr_accessor :debug
10
+
11
+ def self.detectors=(detectors)
12
+ @@detectors = detectors.map do |name, options|
13
+ #require File.expand_path("../detectors/#{name}", __FILE__)
14
+ detector_class = "FaceCrop::Detector::#{name}".constantize
15
+ detector = detector_class.new(options)
16
+ end
17
+ end
18
+
19
+ def initialize(file, options = {}, attachment = nil)
20
+ super(file, options, attachment)
21
+
22
+ raise "No detectors were defined" if @@detectors.nil?
23
+
24
+ faces_regions = []
25
+ faces_parts_regions = []
26
+
27
+ @@detectors.each do |detector|
28
+ begin
29
+ faces_regions += detector.detect(file.path)
30
+ rescue Exception => e
31
+ Rails.logger.error(e)
32
+ end
33
+ end
34
+
35
+ x_coords, y_coords, widths, heights = [], [], [], []
36
+
37
+ faces_regions.each do |region|
38
+ x_coords << region.top_left.x << region.bottom_right.x
39
+ y_coords << region.top_left.y << region.bottom_right.y
40
+ widths << region.width
41
+ heights << region.height
42
+ end
43
+
44
+ @has_faces = faces_regions.size > 0
45
+
46
+ if @has_faces
47
+ @top_left_x = x_coords.min
48
+ @top_left_y = y_coords.min
49
+ @bottom_right_x = x_coords.max
50
+ @bottom_right_y = y_coords.max
51
+
52
+
53
+ #puts @top_left_x.to_s
54
+
55
+ # average faces areas
56
+ average_face_width = widths.sum / widths.size
57
+ average_face_height = heights.sum / heights.size
58
+
59
+ # calculating the surrounding margin of the area that covers all the found faces
60
+ #
61
+
62
+ # new width
63
+ @top_left_x -= average_face_width / 1.2
64
+ @bottom_right_x += average_face_width / 1.2
65
+
66
+ # new height
67
+ #puts ":::#{@top_left_x}---#{average_face_width}"
68
+ #return
69
+
70
+ @top_left_y -= average_face_height / 1.2
71
+ @bottom_right_y += average_face_height / 1.6
72
+
73
+ calculate_bounds
74
+
75
+ # if the new area is smaller than the target geometry, it's scaled so the final image isn't resampled
76
+ #
77
+ if @faces_width < @target_geometry.width
78
+ delta_width = (@target_geometry.width - @faces_width) / 2
79
+ @top_left_x -= delta_width
80
+ @bottom_right_x += delta_width
81
+ calculate_bounds
82
+ end
83
+
84
+ #raise (@target_geometry.height > 0 and @faces_height < @target_geometry.height).to_s
85
+
86
+ if (@target_geometry.height > 0 and @faces_height < @target_geometry.height)
87
+ delta_height = (@target_geometry.height - @faces_height) / 2
88
+ @top_left_y -= delta_height
89
+ @bottom_right_y += delta_height
90
+ calculate_bounds
91
+ end
92
+
93
+ @faces_height = @faces_width if @target_geometry.height == 0
94
+
95
+ @current_geometry = Paperclip::Geometry.new(@faces_width, @faces_height)
96
+
97
+ if @@debug
98
+ parameters = []
99
+ parameters << "-stroke" << "green"
100
+ parameters << "-fill" << "none"
101
+ parameters << faces_regions.map {|r| "-stroke #{r.color} -draw 'rectangle #{r.top_left.x},#{r.top_left.y} #{r.bottom_right.x},#{r.bottom_right.y}'"}
102
+ parameters << ":source"
103
+ parameters << ":dest"
104
+ parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
105
+
106
+ Paperclip.run("convert", parameters, :source => "#{File.expand_path(file.path)}", :dest => "#{File.expand_path(file.path)}")
107
+ end
108
+
109
+
110
+ end
111
+ end
112
+
113
+
114
+ def transformation_command
115
+ return super unless @has_faces
116
+
117
+ scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
118
+ faces_crop = "%dx%d+%d+%d" % [@faces_width, @faces_height, @top_left_x, @top_left_y]
119
+
120
+ trans = []
121
+ trans << "-crop" << %["#{faces_crop}"] << "+repage"
122
+ trans << "-resize" << %["#{scale}"] unless scale.nil? || scale.empty?
123
+ trans << "-crop" << %["#{crop}"] << "+repage" if crop
124
+ trans
125
+ end
126
+
127
+ private
128
+
129
+ # calculate_bounds
130
+ #
131
+ def calculate_bounds
132
+ @top_left_x = 0 if @top_left_x < 0
133
+ @bottom_right_x = @current_geometry.width if @bottom_right_x > @current_geometry.width
134
+
135
+ @top_left_y = 0 if @top_left_y < 0
136
+ @bottom_right_y = @current_geometry.height if @bottom_right_y > @current_geometry.height
137
+
138
+ @faces_width = @bottom_right_x - @top_left_x
139
+ @faces_height = @bottom_right_y - @top_left_y
140
+ end
141
+
142
+ end
143
+ end
data/lib/railtie.rb ADDED
@@ -0,0 +1,22 @@
1
+ module FaceCrop
2
+ class Railtie < Rails::Railtie
3
+ initializer "paperclip-facecrop.extend_has_attachment" do
4
+ raise "Paperclip needed" unless defined?(Paperclip)
5
+ ActiveSupport.on_load :active_record do
6
+
7
+ class ActiveRecord::Base
8
+
9
+ class << self
10
+ def has_attached_file_with_face_crop_cache(name, args)
11
+ has_attached_file_without_face_crop_cache(name, args)
12
+ send("after_#{name}_post_process", lambda { FaceCrop::Detector::Cache.clear })
13
+ end
14
+
15
+ alias_method_chain :has_attached_file, :face_crop_cache
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "paperclip-facecrop"
6
- s.version = "0.0.6"
6
+ s.version = "0.1.0"
7
7
  s.authors = ["Borja Martín"]
8
8
  s.description = %q{Paperclip processor that is aware of the faces detected on the image so that they don't get cropped or aren't shown too small while generating the thumbnails}
9
9
  s.summary = %q{Paperclip processor that is aware of the faces found on the image}
@@ -13,5 +13,4 @@ Gem::Specification.new do |s|
13
13
  s.files = `git ls-files`.split("\n")
14
14
  s.has_rdoc = false
15
15
  s.add_runtime_dependency("paperclip")
16
- s.add_runtime_dependency("opencv", "= 0.0.6")
17
16
  end
metadata CHANGED
@@ -1,99 +1,70 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: paperclip-facecrop
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 6
9
- version: 0.0.6
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
12
- - "Borja Mart\xC3\xADn"
7
+ authors:
8
+ - Borja Martín
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-05-12 00:00:00 +02:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-08-14 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: paperclip
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2153665720 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
31
22
  type: :runtime
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
34
- name: opencv
35
23
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
37
- none: false
38
- requirements:
39
- - - "="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- - 0
44
- - 6
45
- version: 0.0.6
46
- type: :runtime
47
- version_requirements: *id002
48
- description: Paperclip processor that is aware of the faces detected on the image so that they don't get cropped or aren't shown too small while generating the thumbnails
24
+ version_requirements: *2153665720
25
+ description: Paperclip processor that is aware of the faces detected on the image
26
+ so that they don't get cropped or aren't shown too small while generating the thumbnails
49
27
  email: borjam@dagi3d.net
50
28
  executables: []
51
-
52
29
  extensions: []
53
-
54
30
  extra_rdoc_files: []
55
-
56
- files:
31
+ files:
57
32
  - .gitignore
58
33
  - Gemfile
59
34
  - README.md
60
35
  - README_example.jpg
61
36
  - README_example_b.jpg
62
37
  - Rakefile
63
- - lib/opencv_ext.rb
38
+ - lib/detectors/face_com.rb
39
+ - lib/detectors/opencv.rb
40
+ - lib/detectors/opencv_ext.rb
41
+ - lib/face_crop.rb
64
42
  - lib/paperclip-facecrop.rb
43
+ - lib/processor.rb
44
+ - lib/railtie.rb
65
45
  - paperclip-facecrop.gemspec
66
- has_rdoc: true
67
46
  homepage: http://github.com/dagi3d/paperclip-facecrop
68
47
  licenses: []
69
-
70
48
  post_install_message:
71
49
  rdoc_options: []
72
-
73
- require_paths:
50
+ require_paths:
74
51
  - lib
75
- required_ruby_version: !ruby/object:Gem::Requirement
52
+ required_ruby_version: !ruby/object:Gem::Requirement
76
53
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- segments:
81
- - 0
82
- version: "0"
83
- required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
59
  none: false
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- segments:
89
- - 0
90
- version: "0"
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
91
64
  requirements: []
92
-
93
65
  rubyforge_project:
94
- rubygems_version: 1.3.7
66
+ rubygems_version: 1.8.6
95
67
  signing_key:
96
68
  specification_version: 3
97
69
  summary: Paperclip processor that is aware of the faces found on the image
98
70
  test_files: []
99
-