rszr 0.3.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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +74 -0
- data/Rakefile +1 -0
- data/lib/rszr.rb +11 -0
- data/lib/rszr/base.rb +27 -0
- data/lib/rszr/errors.rb +42 -0
- data/lib/rszr/handle.rb +37 -0
- data/lib/rszr/image.rb +183 -0
- data/lib/rszr/lib.rb +64 -0
- data/lib/rszr/version.rb +3 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 47015c365c2eaa3d2fb3178bd8c68b67dcd33428
|
4
|
+
data.tar.gz: 11440490c24628076aa8f42592640c055126e302
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e2353ad80438886866c5246d9483ba09000c3729142324e8e650b00d17415076017cfc0260986a647f3da0305d087fe193ff9fb60095cd0d2d82ab590a35fb53
|
7
|
+
data.tar.gz: ce0fefb4820593aa643a96f3c33d667c2a37c441f132541666cf60c3853866055ef5e1d4e44f7ee32f0d333ac70e095409c0a6835e2a2bb4f4a6b80187eff008
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Matthias Grosser
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Rszr
|
2
|
+
|
3
|
+
Rszr is a fast image resizer.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
In your Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'rszr'
|
11
|
+
```
|
12
|
+
|
13
|
+
### Imlib2
|
14
|
+
|
15
|
+
Rszr requires the Imlib2 library to do the heavy lifting.
|
16
|
+
|
17
|
+
#### OS X
|
18
|
+
|
19
|
+
Using homebrew:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
brew install imlib2
|
23
|
+
```
|
24
|
+
|
25
|
+
### Linux
|
26
|
+
|
27
|
+
Using your favourite package manager:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
yum install imlib2
|
31
|
+
```
|
32
|
+
|
33
|
+
```bash
|
34
|
+
apt-get install libimlib2
|
35
|
+
```
|
36
|
+
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# bounding box 400x300
|
41
|
+
image = Rszr::Image.load('image.jpg')
|
42
|
+
image.resize(400, 300)
|
43
|
+
image.save('resized.jpg')
|
44
|
+
|
45
|
+
# auto height
|
46
|
+
image.resize(400, :auto)
|
47
|
+
|
48
|
+
# auto width
|
49
|
+
image.resize(:auto, 300)
|
50
|
+
|
51
|
+
# scale factor
|
52
|
+
image.resize(0.5)
|
53
|
+
|
54
|
+
# crop
|
55
|
+
image.crop(200, 200, 100, 100)
|
56
|
+
|
57
|
+
# save memory, do not duplicate instance
|
58
|
+
image.resize!(400, :auto)
|
59
|
+
|
60
|
+
# image dimensions
|
61
|
+
image.width => 400
|
62
|
+
image.height => 300
|
63
|
+
image.dimensions => [400, 300]
|
64
|
+
```
|
65
|
+
|
66
|
+
## Speed
|
67
|
+
|
68
|
+
Resizing an 1500x997 JPEG image to 800x532, 100 times:
|
69
|
+
|
70
|
+
Library | Time
|
71
|
+
----------------|-----------
|
72
|
+
MiniMagick | 11.4 s
|
73
|
+
GD2 | 7.2 s
|
74
|
+
Rszr | 3.2 s
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/rszr.rb
ADDED
data/lib/rszr/base.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Rszr
|
2
|
+
module Base
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
Rszr::Lib.delegate(base)
|
6
|
+
Rszr::Lib.delegate(base.singleton_class)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def handle
|
12
|
+
@handle
|
13
|
+
end
|
14
|
+
|
15
|
+
def ptr
|
16
|
+
@handle.ptr
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def assert_valid_keys(hsh, *valid_keys)
|
22
|
+
if unknown_key = (hsh.keys - valid_keys).first
|
23
|
+
raise ArgumentError.new("Unknown key: #{unknown_key.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/rszr/errors.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Rszr
|
2
|
+
class Error < StandardError; end
|
3
|
+
|
4
|
+
class ErrorWithMessage < Error
|
5
|
+
MESSAGES = [nil,
|
6
|
+
'File does not exist',
|
7
|
+
'File is a directory',
|
8
|
+
'Read permission denied',
|
9
|
+
'Unsupported format',
|
10
|
+
'Path too long',
|
11
|
+
'Non-existant path component',
|
12
|
+
'Path component is not a directory',
|
13
|
+
'Path outside address space',
|
14
|
+
'Too many symbolic links',
|
15
|
+
'Out of memory',
|
16
|
+
'Out of file descriptors',
|
17
|
+
'Write permission denied',
|
18
|
+
'Out of disk space',
|
19
|
+
'Unknown error']
|
20
|
+
|
21
|
+
attr_reader :ptr
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@ptr = Fiddle::Pointer.malloc(Rszr::Lib.sizeof('Imlib_Load_Error'))
|
25
|
+
end
|
26
|
+
|
27
|
+
def error?
|
28
|
+
return if ptr.null?
|
29
|
+
0 != ptr[0]
|
30
|
+
end
|
31
|
+
|
32
|
+
def message
|
33
|
+
MESSAGES[ptr[0]] unless ptr.null?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
class FileNotFound < Error; end
|
39
|
+
class LoadError < ErrorWithMessage; end
|
40
|
+
class TransformationError < Error; end
|
41
|
+
class SaveError < ErrorWithMessage; end
|
42
|
+
end
|
data/lib/rszr/handle.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Rszr
|
2
|
+
class Handle
|
3
|
+
attr_reader :ptr, :klass
|
4
|
+
|
5
|
+
def initialize(obj, ptr)
|
6
|
+
@ptr = ptr
|
7
|
+
raise ArgumentError, "#{obj.class.inspect} does not define the finalize class method" unless obj.class.respond_to?(:finalize, true)
|
8
|
+
@klass = obj.class
|
9
|
+
ObjectSpace.define_finalizer(obj, self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def replace!(other_ptr)
|
13
|
+
raise ArgumentError, "Cannot replace pointer with itself" if ptr == other_ptr
|
14
|
+
finalize!
|
15
|
+
@ptr = other_ptr
|
16
|
+
end
|
17
|
+
|
18
|
+
def finalize!(*args)
|
19
|
+
#puts "Finalizing #{args.inspect} #{ptr.inspect}"
|
20
|
+
if !ptr.null? && klass
|
21
|
+
#puts " calling #{args.inspect}"
|
22
|
+
klass.send(:finalize, ptr)
|
23
|
+
ptr = Fiddle::Pointer.new(0)
|
24
|
+
#else
|
25
|
+
#puts " skipping #{args.inspect}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def release!
|
30
|
+
replace! Fiddle::Pointer.new(0)
|
31
|
+
end
|
32
|
+
|
33
|
+
def call(object_id)
|
34
|
+
finalize!(object_id)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/rszr/image.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
module Rszr
|
2
|
+
class Image
|
3
|
+
include Base
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
alias_method :instantiate, :new
|
8
|
+
protected :instantiate
|
9
|
+
|
10
|
+
def new(width, height)
|
11
|
+
ptr = imlib_create_image(width, height)
|
12
|
+
raise Error, 'Could not instantiate image' if ptr.null?
|
13
|
+
instantiate(ptr)
|
14
|
+
end
|
15
|
+
|
16
|
+
def load(path, options = {})
|
17
|
+
path = path.to_s
|
18
|
+
raise FileNotFound unless File.exist?(path)
|
19
|
+
load_error = LoadError.new
|
20
|
+
imlib_set_cache_size(0)
|
21
|
+
ptr = imlib_load_image_with_error_return(path, load_error.ptr)
|
22
|
+
raise load_error, load_error.message if ptr.null?
|
23
|
+
return instantiate(ptr)
|
24
|
+
end
|
25
|
+
alias :open :load
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def finalize(ptr)
|
30
|
+
imlib_context_set_image(ptr)
|
31
|
+
imlib_free_image
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(ptr)
|
37
|
+
@handle = Handle.new(self, ptr)
|
38
|
+
end
|
39
|
+
|
40
|
+
def width
|
41
|
+
context_set_image
|
42
|
+
imlib_image_get_width
|
43
|
+
end
|
44
|
+
|
45
|
+
def height
|
46
|
+
context_set_image
|
47
|
+
imlib_image_get_height
|
48
|
+
end
|
49
|
+
|
50
|
+
def dimensions
|
51
|
+
[width, height]
|
52
|
+
end
|
53
|
+
|
54
|
+
def format
|
55
|
+
context_set_image
|
56
|
+
str_ptr = imlib_image_format
|
57
|
+
return if str_ptr.null?
|
58
|
+
str_ptr.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def resize(*args)
|
62
|
+
instantiate(create_resized_image(*args))
|
63
|
+
end
|
64
|
+
|
65
|
+
def resize!(*args)
|
66
|
+
handle.replace!(create_resized_image(*args))
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def crop(*args)
|
71
|
+
instantiate(create_cropped_image(*args))
|
72
|
+
end
|
73
|
+
|
74
|
+
def crop!(*args)
|
75
|
+
handle.replace!(create_cropped_image(*args))
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
def save(path, format = nil)
|
80
|
+
context_set_image
|
81
|
+
format ||= format_from_filename(path) || 'jpg'
|
82
|
+
imlib_image_set_format(format)
|
83
|
+
save_error = SaveError.new
|
84
|
+
imlib_save_image_with_error_return(path, save_error.ptr)
|
85
|
+
raise save_error, save_error.message if save_error.error?
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
def inspect
|
90
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} width=#{width} height=#{height} format=#{format.inspect}>"
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
# 0.5 0 < scale < 1
|
96
|
+
# 400, 300 fit box
|
97
|
+
# 400, :auto fit width, auto height
|
98
|
+
# :auto, 300 auto width, fit height
|
99
|
+
# 400, 300, crop: :center_middle
|
100
|
+
# 400, 300, background: rgba
|
101
|
+
# 400, 300, aspect: false
|
102
|
+
|
103
|
+
def create_resized_image(*args)
|
104
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
105
|
+
assert_valid_keys options, :crop, :background, :skew #:extend, :width, :height, :max_width, :max_height, :box
|
106
|
+
context_set_image
|
107
|
+
x, y, = 0, 0
|
108
|
+
if args.size == 1
|
109
|
+
scale = args.first
|
110
|
+
raise ArgumentError, "scale #{scale.inspect} out of range" unless scale > 0 && scale < 1
|
111
|
+
new_width = width.to_f * scale
|
112
|
+
new_height = height.to_f * scale
|
113
|
+
elsif args.size == 2
|
114
|
+
box_width, box_height = args
|
115
|
+
if :auto == box_width && box_height.is_a?(Numeric)
|
116
|
+
new_height = box_height
|
117
|
+
new_width = box_height.to_f / height.to_f * width.to_f
|
118
|
+
elsif box_width.is_a?(Numeric) && :auto == box_height
|
119
|
+
new_width = box_width
|
120
|
+
new_height = box_width.to_f / width.to_f * height.to_f
|
121
|
+
elsif box_width.is_a?(Numeric) && box_height.is_a?(Numeric)
|
122
|
+
if options[:skew]
|
123
|
+
new_width, new_height = box_width, box_height
|
124
|
+
elsif options[:crop]
|
125
|
+
# TODO: calculate x, y offset if crop
|
126
|
+
else
|
127
|
+
scale = width.to_f / height.to_f
|
128
|
+
box_scale = box_width.to_f / box_height.to_f
|
129
|
+
if scale >= box_scale # wider
|
130
|
+
new_width = box_width
|
131
|
+
new_height = height.to_f * box_width.to_f / width.to_f
|
132
|
+
else # narrower
|
133
|
+
new_height = box_height
|
134
|
+
new_width = width.to_f * box_height.to_f / height.to_f
|
135
|
+
end
|
136
|
+
end
|
137
|
+
else
|
138
|
+
raise ArgumentError, "unconclusive arguments #{args.inspect} #{options.inspect}"
|
139
|
+
end
|
140
|
+
else
|
141
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2)"
|
142
|
+
end
|
143
|
+
|
144
|
+
#new_width = options[:width] || imlib_image_get_width
|
145
|
+
#new_height = options[:height] || imlib_image_get_height
|
146
|
+
#if max_width = options[:max_width] and new_width > max_width
|
147
|
+
# scale = max_width.to_f / new_width.to_f
|
148
|
+
# width = max_width
|
149
|
+
# new_height = (scale * new_height).to_i
|
150
|
+
#end
|
151
|
+
#if max_height = options[:max_height] and new_height > max_height
|
152
|
+
# scale = max_height.to_f / new_height.to_f
|
153
|
+
# new_height = max_height
|
154
|
+
# new_width = (scale * new_width).to_i
|
155
|
+
#end
|
156
|
+
|
157
|
+
imlib_context_set_anti_alias(1)
|
158
|
+
resized_ptr = imlib_create_cropped_scaled_image(x, y, imlib_image_get_width, imlib_image_get_height, new_width.round, new_height.round)
|
159
|
+
raise TransformationError, "error resizing image" if resized_ptr.null?
|
160
|
+
resized_ptr
|
161
|
+
end
|
162
|
+
|
163
|
+
def create_cropped_image(x, y, width, height)
|
164
|
+
context_set_image
|
165
|
+
cropped_ptr = imlib_create_cropped_image(x, y, width, height)
|
166
|
+
raise TransformationError, 'error cropping image' if cropped_ptr.null?
|
167
|
+
cropped_ptr
|
168
|
+
end
|
169
|
+
|
170
|
+
def format_from_filename(path)
|
171
|
+
File.extname(path)[1..-1]
|
172
|
+
end
|
173
|
+
|
174
|
+
def context_set_image
|
175
|
+
imlib_context_set_image(ptr)
|
176
|
+
end
|
177
|
+
|
178
|
+
def instantiate(ptr)
|
179
|
+
self.class.send(:instantiate, ptr)
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
end
|
data/lib/rszr/lib.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Rszr
|
2
|
+
|
3
|
+
module Lib
|
4
|
+
extend Fiddle::Importer
|
5
|
+
|
6
|
+
dlload case RbConfig::CONFIG['arch']
|
7
|
+
when /darwin/ then 'libImlib2.dylib'
|
8
|
+
when /mswin/, /cygwin/ then 'imlib2.dll'
|
9
|
+
else
|
10
|
+
'libImlib2.so'
|
11
|
+
end
|
12
|
+
|
13
|
+
typealias 'Imlib_Image', 'void *'
|
14
|
+
typealias 'Imlib_Context', 'void *'
|
15
|
+
typealias 'enum', 'int'
|
16
|
+
typealias 'Imlib_Load_Error', 'enum'
|
17
|
+
|
18
|
+
#typedef void *Imlib_Color_Modifier;
|
19
|
+
#typedef void *Imlib_Updates;
|
20
|
+
#typedef void *Imlib_Font;
|
21
|
+
#typedef void *Imlib_Color_Range;
|
22
|
+
#typedef void *Imlib_Filter;
|
23
|
+
#typedef struct _imlib_border Imlib_Border;
|
24
|
+
#typedef struct _imlib_color Imlib_Color;
|
25
|
+
#typedef void *ImlibPolygon;
|
26
|
+
|
27
|
+
extern 'int imlib_get_cache_size()'
|
28
|
+
extern 'void imlib_set_cache_size(int)'
|
29
|
+
|
30
|
+
extern 'Imlib_Image imlib_load_image(const char *)'
|
31
|
+
extern 'Imlib_Image imlib_load_image_without_cache(const char *)'
|
32
|
+
extern 'Imlib_Image imlib_load_image_with_error_return(const char *, Imlib_Load_Error *)'
|
33
|
+
extern 'Imlib_Image imlib_create_image(int, int)'
|
34
|
+
extern 'void imlib_context_set_image(Imlib_Image)'
|
35
|
+
extern 'int imlib_image_get_width()'
|
36
|
+
extern 'int imlib_image_get_height()'
|
37
|
+
extern 'void imlib_context_set_anti_alias(char)'
|
38
|
+
|
39
|
+
# source_x, source_y, source_width, source_height, destination_width, destination_height
|
40
|
+
extern 'Imlib_Image imlib_create_cropped_scaled_image(int, int, int, int, int, int)'
|
41
|
+
# x, y, width, height
|
42
|
+
extern 'Imlib_Image imlib_create_cropped_image(int, int, int, int)'
|
43
|
+
|
44
|
+
extern 'char * imlib_image_format()'
|
45
|
+
extern 'void imlib_image_set_format(const char *)'
|
46
|
+
extern 'void imlib_save_image(const char *)'
|
47
|
+
extern 'void imlib_save_image_with_error_return(const char *, Imlib_Load_Error *)'
|
48
|
+
|
49
|
+
extern 'void imlib_free_image()'
|
50
|
+
extern 'void imlib_free_image_and_decache()'
|
51
|
+
|
52
|
+
def self.delegate(base)
|
53
|
+
Lib.methods.grep(/\Aimlib_/).each do |method|
|
54
|
+
line_no = __LINE__; str = %Q{
|
55
|
+
def #{method}(*args, &block)
|
56
|
+
Lib.#{method}(*args, &block)
|
57
|
+
end
|
58
|
+
}
|
59
|
+
base.class_eval(str, __FILE__, line_no)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/lib/rszr/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rszr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthias Grosser
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: gd2-ffij
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: mini_magick
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Fast image resizer - do one thing and do it fast.
|
112
|
+
email:
|
113
|
+
- mtgrosser@gmx.net
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- LICENSE
|
119
|
+
- README.md
|
120
|
+
- Rakefile
|
121
|
+
- lib/rszr.rb
|
122
|
+
- lib/rszr/base.rb
|
123
|
+
- lib/rszr/errors.rb
|
124
|
+
- lib/rszr/handle.rb
|
125
|
+
- lib/rszr/image.rb
|
126
|
+
- lib/rszr/lib.rb
|
127
|
+
- lib/rszr/version.rb
|
128
|
+
homepage: https://github.com/mtgrosser/rszr
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.4.5
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Fast image resizer
|
152
|
+
test_files: []
|