croptoelie 0.4.0 → 0.4.1
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/VERSION +1 -1
- data/croptoelie.gemspec +2 -2
- data/lib/croptoelie.rb +53 -50
- data/test/fixtures/20x20.png +0 -0
- data/test/{entropyish.png → fixtures/entropyish.png} +0 -0
- data/test/fixtures/entropyish.txt +1 -0
- data/test/fixtures/errors/flo-rida.png +0 -0
- data/test/fixtures/errors/hollywood-undead.jpg +0 -0
- data/test/fixtures/errors/maroon-5.jpg +0 -0
- data/test/fixtures/errors/yo-gotti.jpg +0 -0
- data/test/test_croptoelie.rb +42 -5
- metadata +105 -73
- data/.rvmrc +0 -1
- data/test/entropyish.txt +0 -0
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.4.
|
|
1
|
+
0.4.1
|
data/croptoelie.gemspec
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Generated by jeweler
|
|
1
|
+
# Generated by jeweler
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{croptoelie}
|
|
8
|
-
s.version = "0.4.
|
|
8
|
+
s.version = "0.4.1"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Bèr Kessels"]
|
data/lib/croptoelie.rb
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
require 'RMagick'
|
|
2
2
|
class CropToelie
|
|
3
3
|
include Magick
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
attr_accessor :orig
|
|
6
6
|
attr_accessor :steps
|
|
7
|
-
|
|
8
|
-
# Create a new CropToelie object from a ImageList single image object.
|
|
9
|
-
# If you want to provide a file by its path use CropToelie.from_file('/path/to/image.png').
|
|
7
|
+
|
|
8
|
+
# Create a new CropToelie object from a ImageList single image object.
|
|
9
|
+
# If you want to provide a file by its path use CropToelie.from_file('/path/to/image.png').
|
|
10
10
|
def initialize(image)
|
|
11
11
|
@image = image
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
# Hardcoded (but overridable) defaults.
|
|
14
14
|
@steps = 10
|
|
15
15
|
|
|
16
16
|
# Preprocess image.
|
|
17
17
|
@image = @image.quantize
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
# Prepare some often-used internal variables.
|
|
20
20
|
@rows = @image.rows
|
|
21
21
|
@columns = @image.columns
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
# Open create a croptoelie from a file on disk.
|
|
25
25
|
def self.from_file(image_path)
|
|
26
26
|
image = ImageList.new(image_path).last
|
|
27
27
|
return CropToelie.new(image)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
# Crops an image to width x height
|
|
30
|
+
# Crops an image to width x height
|
|
31
31
|
def smart_crop(width, height)
|
|
32
32
|
sq = square(width, height)
|
|
33
33
|
return @image.crop!(sq[:left], sq[:top], width, height, true)
|
|
@@ -35,11 +35,11 @@ class CropToelie
|
|
|
35
35
|
|
|
36
36
|
# Squares an image (with smart_square) and then scales that to width, heigh
|
|
37
37
|
def smart_crop_and_scale(width, height)
|
|
38
|
-
smart_square
|
|
38
|
+
smart_square
|
|
39
39
|
return @image.scale!(width, height)
|
|
40
40
|
end
|
|
41
|
-
|
|
42
|
-
# Squares an image by slicing off the least interesting parts.
|
|
41
|
+
|
|
42
|
+
# Squares an image by slicing off the least interesting parts.
|
|
43
43
|
# Usefull for squaring images such as thumbnails. Usefull before scaling.
|
|
44
44
|
def smart_square
|
|
45
45
|
if @rows != @columns #None-square images must be shaved off.
|
|
@@ -52,21 +52,21 @@ class CropToelie
|
|
|
52
52
|
sq = square(crop_width, crop_height)
|
|
53
53
|
@image.crop!(sq[:left], sq[:top], crop_width, crop_height, true)
|
|
54
54
|
end
|
|
55
|
-
|
|
56
|
-
@image
|
|
55
|
+
|
|
56
|
+
@image
|
|
57
57
|
end
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
# Finds the most interesting square with size width x height.
|
|
60
|
-
#
|
|
60
|
+
#
|
|
61
61
|
# Returns a hash {:left => left, :top => top, :right => right, :bottom => bottom}
|
|
62
62
|
def square(width, height)
|
|
63
63
|
return smart_crop_by_trim(width, height)
|
|
64
64
|
end
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
private
|
|
67
|
-
# Determines if the image should be cropped.
|
|
68
|
-
# Image should be cropped if original is larger then requested size.
|
|
69
|
-
# In all other cases, it should not.
|
|
67
|
+
# Determines if the image should be cropped.
|
|
68
|
+
# Image should be cropped if original is larger then requested size.
|
|
69
|
+
# In all other cases, it should not.
|
|
70
70
|
def should_crop?
|
|
71
71
|
return (@columns > @width) && (@rows < @height)
|
|
72
72
|
end
|
|
@@ -77,38 +77,41 @@ class CropToelie
|
|
|
77
77
|
width, height = right, bottom
|
|
78
78
|
step_size = step_size(requested_x, requested_y)
|
|
79
79
|
|
|
80
|
-
#
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
# Avoid attempts to slice less then one pixel.
|
|
81
|
+
if step_size > 0
|
|
82
|
+
# Slice from left and right edges until the correct width is reached.
|
|
83
|
+
while (width > requested_x)
|
|
84
|
+
slice_width = [(width - requested_x), step_size].min
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
left_entropy = entropy_slice(@image, left, 0, slice_width, bottom)
|
|
87
|
+
right_entropy = entropy_slice(@image, (right - slice_width), 0, slice_width, bottom)
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
#remove the slice with the least entropy
|
|
90
|
+
if left_entropy < right_entropy
|
|
91
|
+
left += slice_width
|
|
92
|
+
else
|
|
93
|
+
right -= slice_width
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
width = (right - left)
|
|
92
97
|
end
|
|
93
|
-
|
|
94
|
-
width = (right - left)
|
|
95
|
-
end
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
# Slice from top and bottom edges until the correct height is reached.
|
|
100
|
+
while (height > requested_y)
|
|
101
|
+
slice_height = [(height - step_size), step_size].min
|
|
102
|
+
|
|
103
|
+
top_entropy = entropy_slice(@image, 0, top, @columns, slice_height)
|
|
104
|
+
bottom_entropy = entropy_slice(@image, 0, (bottom - slice_height), @columns, slice_height)
|
|
105
|
+
|
|
106
|
+
#remove the slice with the least entropy
|
|
107
|
+
if top_entropy < bottom_entropy
|
|
108
|
+
top += slice_height
|
|
109
|
+
else
|
|
110
|
+
bottom -= slice_height
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
height = (bottom - top)
|
|
109
114
|
end
|
|
110
|
-
|
|
111
|
-
height = (bottom - top)
|
|
112
115
|
end
|
|
113
116
|
|
|
114
117
|
square = {:left => left, :top => top, :right => right, :bottom => bottom}
|
|
@@ -119,22 +122,22 @@ class CropToelie
|
|
|
119
122
|
slice = image_data.crop(x, y, width, height)
|
|
120
123
|
entropy = entropy(slice)
|
|
121
124
|
end
|
|
122
|
-
|
|
125
|
+
|
|
123
126
|
# Compute the entropy of an image, defined as -sum(p.*log2(p)).
|
|
124
127
|
# Note: instead of log2, only available in ruby > 1.9, we use
|
|
125
128
|
# log(p)/log(2). which has the same effect.
|
|
126
129
|
def entropy(image_slice)
|
|
127
130
|
hist = image_slice.color_histogram
|
|
128
131
|
hist_size = hist.values.inject{|sum,x| sum ? sum + x : x }.to_f
|
|
129
|
-
|
|
132
|
+
|
|
130
133
|
entropy = 0
|
|
131
|
-
hist.values.each do |h|
|
|
134
|
+
hist.values.each do |h|
|
|
132
135
|
p = h.to_f / hist_size
|
|
133
136
|
entropy += (p * (Math.log(p)/Math.log(2))) if p != 0
|
|
134
137
|
end
|
|
135
138
|
return entropy * -1
|
|
136
139
|
end
|
|
137
|
-
|
|
140
|
+
|
|
138
141
|
def step_size(requested_x, requested_y)
|
|
139
142
|
((([@rows - requested_x, @columns - requested_y].max)/2)/@steps).to_i
|
|
140
143
|
end
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This is not an image.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/test/test_croptoelie.rb
CHANGED
|
@@ -2,9 +2,14 @@ require 'helper'
|
|
|
2
2
|
|
|
3
3
|
class TestCroptoelie < Test::Unit::TestCase
|
|
4
4
|
def setup
|
|
5
|
-
@filename = File.join(File.expand_path(File.dirname(__FILE__)), "entropyish.png")
|
|
5
|
+
@filename = File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "entropyish.png")
|
|
6
6
|
@image = Magick::ImageList.new(@filename).last
|
|
7
|
+
|
|
8
|
+
@twenty_twenty = Magick::ImageList.new(
|
|
9
|
+
File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", "20x20.png")
|
|
10
|
+
).last
|
|
7
11
|
end
|
|
12
|
+
|
|
8
13
|
should "initialize a croptoelie image from an ImageList item" do
|
|
9
14
|
img = CropToelie.new(@image)
|
|
10
15
|
assert_equal(img.class, CropToelie)
|
|
@@ -16,27 +21,59 @@ class TestCroptoelie < Test::Unit::TestCase
|
|
|
16
21
|
|
|
17
22
|
should "fail on creating a croptoelie image from a textfile" do
|
|
18
23
|
assert_raise Magick::ImageMagickError, NoMethodError do
|
|
19
|
-
CropToelie.new(File.join(File.expand_path(File.dirname(__FILE__)), "entropyish.txt"))
|
|
24
|
+
CropToelie.new(File.join(File.expand_path(File.dirname(__FILE__)), "fixtures","entropyish.txt"))
|
|
20
25
|
end
|
|
21
26
|
end
|
|
22
|
-
|
|
27
|
+
|
|
23
28
|
should "crop to 100x100 without scaling with smart_crop" do
|
|
24
29
|
img = CropToelie.new(@image)
|
|
25
30
|
img = img.smart_crop(100, 100)
|
|
26
31
|
size = [img.rows, img.columns]
|
|
27
32
|
assert_equal(size, [100, 100])
|
|
28
33
|
end
|
|
29
|
-
|
|
34
|
+
|
|
30
35
|
should "crop to 100x100 with scaling with smart_crop_and_scale" do
|
|
31
36
|
img = CropToelie.new(@image)
|
|
32
37
|
img = img.smart_crop_and_scale(100, 100)
|
|
33
38
|
size = [img.rows, img.columns]
|
|
34
39
|
assert_equal(size, [100, 100])
|
|
35
40
|
end
|
|
36
|
-
|
|
41
|
+
|
|
37
42
|
should "square image without scaling" do
|
|
38
43
|
img = CropToelie.new(@image)
|
|
39
44
|
img = img.smart_square
|
|
40
45
|
assert_equal(img.rows, img.columns)
|
|
41
46
|
end
|
|
47
|
+
|
|
48
|
+
should "not crop small images" do
|
|
49
|
+
img = CropToelie.new(@twenty_twenty)
|
|
50
|
+
img = img.smart_crop(100, 100)
|
|
51
|
+
size = [img.rows, img.columns]
|
|
52
|
+
assert_equal([20, 20], size)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should "still crop a slice of one pixel" do
|
|
56
|
+
img = CropToelie.new(@twenty_twenty)
|
|
57
|
+
img = img.smart_crop(19, 19)
|
|
58
|
+
size = [img.rows, img.columns]
|
|
59
|
+
assert_equal([19, 19], size)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
###########################################################################
|
|
63
|
+
# Images reported to fail by issue #5 #
|
|
64
|
+
###########################################################################
|
|
65
|
+
[:smart_crop, :smart_crop_and_scale, :smart_square].each do |method|
|
|
66
|
+
full_path = File.join File.dirname(__FILE__), "fixtures", "errors"
|
|
67
|
+
Dir.open(full_path).select{|f| !File.directory?(f)}.each do |file|
|
|
68
|
+
|
|
69
|
+
should "'not fail on reported-as-broken image '#{file}' with '#{method}'" do
|
|
70
|
+
realpath = File.realpath(File.join full_path, file)
|
|
71
|
+
|
|
72
|
+
img = CropToelie.new(Magick::ImageList.new(realpath).last)
|
|
73
|
+
img = img.smart_crop(200, 200)
|
|
74
|
+
size = [img.rows, img.columns]
|
|
75
|
+
assert_equal(size, [200, 200])
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
42
79
|
end
|
metadata
CHANGED
|
@@ -1,96 +1,126 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: croptoelie
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.1
|
|
4
5
|
prerelease:
|
|
5
|
-
version: 0.4.0
|
|
6
6
|
platform: ruby
|
|
7
|
-
authors:
|
|
8
|
-
-
|
|
7
|
+
authors:
|
|
8
|
+
- Bèr Kessels
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
dependencies:
|
|
16
|
-
- !ruby/object:Gem::Dependency
|
|
12
|
+
date: 2012-11-18 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
17
15
|
name: rmagick
|
|
18
|
-
requirement:
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
19
17
|
none: false
|
|
20
|
-
requirements:
|
|
21
|
-
- -
|
|
22
|
-
- !ruby/object:Gem::Version
|
|
23
|
-
version:
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
24
22
|
type: :runtime
|
|
25
23
|
prerelease: false
|
|
26
|
-
version_requirements:
|
|
27
|
-
|
|
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
|
|
28
31
|
name: shoulda
|
|
29
|
-
requirement:
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
33
|
none: false
|
|
31
|
-
requirements:
|
|
32
|
-
- -
|
|
33
|
-
- !ruby/object:Gem::Version
|
|
34
|
-
version:
|
|
34
|
+
requirements:
|
|
35
|
+
- - ! '>='
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
35
38
|
type: :development
|
|
36
39
|
prerelease: false
|
|
37
|
-
version_requirements:
|
|
38
|
-
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
39
47
|
name: bundler
|
|
40
|
-
requirement:
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
41
49
|
none: false
|
|
42
|
-
requirements:
|
|
50
|
+
requirements:
|
|
43
51
|
- - ~>
|
|
44
|
-
- !ruby/object:Gem::Version
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
45
53
|
version: 1.0.0
|
|
46
54
|
type: :development
|
|
47
55
|
prerelease: false
|
|
48
|
-
version_requirements:
|
|
49
|
-
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 1.0.0
|
|
62
|
+
- !ruby/object:Gem::Dependency
|
|
50
63
|
name: jeweler
|
|
51
|
-
requirement:
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
52
65
|
none: false
|
|
53
|
-
requirements:
|
|
66
|
+
requirements:
|
|
54
67
|
- - ~>
|
|
55
|
-
- !ruby/object:Gem::Version
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
56
69
|
version: 1.5.2
|
|
57
70
|
type: :development
|
|
58
71
|
prerelease: false
|
|
59
|
-
version_requirements:
|
|
60
|
-
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ~>
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: 1.5.2
|
|
78
|
+
- !ruby/object:Gem::Dependency
|
|
61
79
|
name: rcov
|
|
62
|
-
requirement:
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
81
|
none: false
|
|
64
|
-
requirements:
|
|
65
|
-
- -
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
82
|
+
requirements:
|
|
83
|
+
- - ! '>='
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
68
86
|
type: :development
|
|
69
87
|
prerelease: false
|
|
70
|
-
version_requirements:
|
|
71
|
-
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
94
|
+
- !ruby/object:Gem::Dependency
|
|
72
95
|
name: rmagick
|
|
73
|
-
requirement:
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
74
97
|
none: false
|
|
75
|
-
requirements:
|
|
76
|
-
- -
|
|
77
|
-
- !ruby/object:Gem::Version
|
|
98
|
+
requirements:
|
|
99
|
+
- - ! '>'
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
78
101
|
version: 2.11.0
|
|
79
102
|
type: :runtime
|
|
80
103
|
prerelease: false
|
|
81
|
-
version_requirements:
|
|
82
|
-
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>'
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: 2.11.0
|
|
110
|
+
description: ! 'Crops images based on entropy: leaving the most interesting part intact.
|
|
111
|
+
Don''t expect this to be a replacement for human cropping, it is an algorythm and
|
|
112
|
+
not an extremely smart one at that :). Best results achieved in combination with
|
|
113
|
+
scaling: the cropping is then only used to square the image, cutting off the least
|
|
114
|
+
interesting part. The trimming simply chops off te edge that is least interesting,
|
|
115
|
+
and continues doing so, untill it reached the requested size.'
|
|
83
116
|
email: ber@webschuur.com
|
|
84
117
|
executables: []
|
|
85
|
-
|
|
86
118
|
extensions: []
|
|
87
|
-
|
|
88
|
-
extra_rdoc_files:
|
|
119
|
+
extra_rdoc_files:
|
|
89
120
|
- LICENSE.txt
|
|
90
121
|
- README.md
|
|
91
|
-
files:
|
|
122
|
+
files:
|
|
92
123
|
- .document
|
|
93
|
-
- .rvmrc
|
|
94
124
|
- Gemfile
|
|
95
125
|
- Gemfile.lock
|
|
96
126
|
- LICENSE.txt
|
|
@@ -102,43 +132,45 @@ files:
|
|
|
102
132
|
- doc/croptoelie_test.rb
|
|
103
133
|
- doc/histogram.rb
|
|
104
134
|
- lib/croptoelie.rb
|
|
105
|
-
- test/
|
|
106
|
-
- test/entropyish.
|
|
135
|
+
- test/fixtures/20x20.png
|
|
136
|
+
- test/fixtures/entropyish.png
|
|
137
|
+
- test/fixtures/entropyish.txt
|
|
138
|
+
- test/fixtures/errors/flo-rida.png
|
|
139
|
+
- test/fixtures/errors/hollywood-undead.jpg
|
|
140
|
+
- test/fixtures/errors/maroon-5.jpg
|
|
141
|
+
- test/fixtures/errors/yo-gotti.jpg
|
|
107
142
|
- test/helper.rb
|
|
108
143
|
- test/profiler.rb
|
|
109
144
|
- test/test_croptoelie.rb
|
|
110
|
-
has_rdoc: true
|
|
111
145
|
homepage: http://github.com/berkes/croptoelie
|
|
112
|
-
licenses:
|
|
146
|
+
licenses:
|
|
113
147
|
- MIT
|
|
114
148
|
post_install_message:
|
|
115
149
|
rdoc_options: []
|
|
116
|
-
|
|
117
|
-
require_paths:
|
|
150
|
+
require_paths:
|
|
118
151
|
- lib
|
|
119
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
153
|
none: false
|
|
121
|
-
requirements:
|
|
122
|
-
- -
|
|
123
|
-
- !ruby/object:Gem::Version
|
|
124
|
-
|
|
125
|
-
segments:
|
|
154
|
+
requirements:
|
|
155
|
+
- - ! '>='
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '0'
|
|
158
|
+
segments:
|
|
126
159
|
- 0
|
|
127
|
-
|
|
128
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
|
+
hash: 259147617
|
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
162
|
none: false
|
|
130
|
-
requirements:
|
|
131
|
-
- -
|
|
132
|
-
- !ruby/object:Gem::Version
|
|
133
|
-
version:
|
|
163
|
+
requirements:
|
|
164
|
+
- - ! '>='
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
134
167
|
requirements: []
|
|
135
|
-
|
|
136
168
|
rubyforge_project:
|
|
137
|
-
rubygems_version: 1.
|
|
169
|
+
rubygems_version: 1.8.24
|
|
138
170
|
signing_key:
|
|
139
171
|
specification_version: 3
|
|
140
172
|
summary: Content aware cropper.
|
|
141
|
-
test_files:
|
|
173
|
+
test_files:
|
|
142
174
|
- test/helper.rb
|
|
143
175
|
- test/profiler.rb
|
|
144
176
|
- test/test_croptoelie.rb
|
data/.rvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
rvm ruby-1.9.2-p0@croptoelie
|
data/test/entropyish.txt
DELETED
|
File without changes
|