rszr 0.4.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +129 -12
- data/Rakefile +6 -0
- data/ext/rszr/errors.c +68 -0
- data/ext/rszr/errors.h +15 -0
- data/ext/rszr/extconf.rb +18 -0
- data/ext/rszr/image.c +482 -0
- data/ext/rszr/image.h +12 -0
- data/ext/rszr/rszr.c +17 -0
- data/ext/rszr/rszr.h +11 -0
- data/lib/rszr/batch_transformation.rb +24 -0
- data/lib/rszr/buffered.rb +25 -0
- data/lib/rszr/identification.rb +60 -0
- data/lib/rszr/image.rb +151 -98
- data/lib/rszr/image_processing.rb +82 -0
- data/lib/rszr/orientation.rb +107 -0
- data/lib/rszr/stream.rb +61 -0
- data/lib/rszr/version.rb +1 -1
- data/lib/rszr.rb +21 -7
- metadata +27 -114
- data/lib/rszr/base.rb +0 -29
- data/lib/rszr/errors.rb +0 -42
- data/lib/rszr/handle.rb +0 -37
- data/lib/rszr/lib.rb +0 -73
- data/lib/rszr/lock.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 035d5f7341e71cdc9b5ba70de6e116acd8d8459e
|
4
|
+
data.tar.gz: 3119e97a26295db8f3931821d6ae835aaa6166ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 003305cff18cc4678a13f238e17d709351a36efea86b5ca2de751d15f933211c0d107601f2be6aa70dfc92a30a87615fdf3372dae26552190d21911451d33445
|
7
|
+
data.tar.gz: 732e05777cf4adc9c87515e043a226ed42bd56d0c76e3a28bf645fa22b492fed2cb2a473dbdccd4980b76a23b2d7bf579ec45c68a305a07c77f890697ff82e66
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
[![Gem Version](https://badge.fury.io/rb/rszr.svg)](http://badge.fury.io/rb/rszr) [![
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/rszr.svg)](http://badge.fury.io/rb/rszr) [![build](https://github.com/mtgrosser/rszr/actions/workflows/build.yml/badge.svg)](https://github.com/mtgrosser/rszr/actions/workflows/build.yml)
|
2
2
|
# Rszr - fast image resizer for Ruby
|
3
3
|
|
4
|
-
Rszr is an image resizer for Ruby based on the Imlib2 library.
|
4
|
+
Rszr is an image resizer for Ruby based on the Imlib2 library.
|
5
|
+
It is faster and consumes less memory than MiniMagick, GD2 and VIPS, and comes with an optional drop-in interface for Rails ActiveStorage image processing.
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
@@ -13,7 +14,7 @@ gem 'rszr'
|
|
13
14
|
|
14
15
|
### Imlib2
|
15
16
|
|
16
|
-
Rszr requires the Imlib2 library to do the heavy lifting.
|
17
|
+
Rszr requires the `Imlib2` library to do the heavy lifting.
|
17
18
|
|
18
19
|
#### OS X
|
19
20
|
|
@@ -27,10 +28,14 @@ brew install imlib2
|
|
27
28
|
|
28
29
|
Using your favourite package manager:
|
29
30
|
|
31
|
+
##### RedHat-based
|
32
|
+
|
30
33
|
```bash
|
31
34
|
yum install imlib2 imlib2-devel
|
32
35
|
```
|
33
36
|
|
37
|
+
##### Debian-based
|
38
|
+
|
34
39
|
```bash
|
35
40
|
apt-get install libimlib2 libimlib2-dev
|
36
41
|
```
|
@@ -45,6 +50,25 @@ image.resize(400, 300)
|
|
45
50
|
# save it
|
46
51
|
image.save('resized.jpg')
|
47
52
|
|
53
|
+
# save it as PNG
|
54
|
+
image.save('resized.png')
|
55
|
+
```
|
56
|
+
|
57
|
+
### Image info
|
58
|
+
```ruby
|
59
|
+
image.width => 400
|
60
|
+
image.height => 300
|
61
|
+
image.dimensions => [400, 300]
|
62
|
+
image.format => "jpeg"
|
63
|
+
```
|
64
|
+
|
65
|
+
### Transformations
|
66
|
+
|
67
|
+
For each transformation, there is a bang! and non-bang method.
|
68
|
+
The bang method changes the image in place, while the non-bang method
|
69
|
+
creates a copy of the image in memory.
|
70
|
+
|
71
|
+
```ruby
|
48
72
|
# auto height
|
49
73
|
image.resize(400, :auto)
|
50
74
|
|
@@ -57,26 +81,119 @@ image.resize(0.5)
|
|
57
81
|
# crop
|
58
82
|
image.crop(200, 200, 100, 100)
|
59
83
|
|
84
|
+
# rotate three times 90 deg clockwise
|
85
|
+
image.turn!(3)
|
86
|
+
|
87
|
+
# rotate one time 90 deg counterclockwise
|
88
|
+
image.turn!(-1)
|
89
|
+
|
90
|
+
# rotate by arbitrary angle
|
91
|
+
image.rotate(45)
|
92
|
+
|
93
|
+
# flip vertically
|
94
|
+
image.flip
|
95
|
+
|
96
|
+
# flop horizontally
|
97
|
+
image.flop
|
98
|
+
|
99
|
+
# initialize copy
|
100
|
+
image.dup
|
101
|
+
|
60
102
|
# save memory, do not duplicate instance
|
61
103
|
image.resize!(400, :auto)
|
104
|
+
```
|
62
105
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
106
|
+
### Filters
|
107
|
+
|
108
|
+
Filters also support bang! and non-bang methods.
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
# sharpen image by pixel radius
|
112
|
+
image.sharpen!(1)
|
113
|
+
|
114
|
+
# blur image by pixel radius
|
115
|
+
image.blur!(1)
|
116
|
+
|
117
|
+
# brighten
|
118
|
+
image.brighten(0.1)
|
119
|
+
|
120
|
+
# darken
|
121
|
+
image.brighten(-0.1)
|
122
|
+
|
123
|
+
# contrast
|
124
|
+
image.contrast(0.5)
|
125
|
+
|
126
|
+
# gamma
|
127
|
+
image.gamma(1.1)
|
128
|
+
```
|
129
|
+
|
130
|
+
### Image auto orientation
|
131
|
+
|
132
|
+
Auto-rotation is supported for JPEG and TIFF files that include the necessary
|
133
|
+
EXIF metadata.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
# load and autorotate
|
137
|
+
image = Rszr::Image.load('image.jpg', autorotate: true)
|
138
|
+
```
|
139
|
+
|
140
|
+
To enable autorotation by default:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# auto-rotate by default, for Rails apps put this into an initializer
|
144
|
+
Rszr.autorotate = true
|
145
|
+
```
|
146
|
+
|
147
|
+
## Rails / ActiveStorage interface
|
148
|
+
|
149
|
+
Rszr provides a drop-in interface to the `image_resizing` gem.
|
150
|
+
It is faster than both `mini_magick` and `vips` and way easier to install than the latter.
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
# Gemfile
|
154
|
+
gem 'image_resizing'
|
155
|
+
gem 'rszr'
|
156
|
+
|
157
|
+
# config/initializers/rszr.rb
|
158
|
+
require 'rszr/image_processing'
|
159
|
+
|
160
|
+
# config/application.rb
|
161
|
+
config.active_storage.variant_processor = :rszr
|
162
|
+
```
|
163
|
+
|
164
|
+
When creating image variants, you can use all of Rszr's transformation methods:
|
165
|
+
|
166
|
+
```erb
|
167
|
+
<%= image_tag user.avatar.variant(resize_to_fit: [300, 200]) %>
|
168
|
+
```
|
169
|
+
|
170
|
+
## Loading from and saving to memory
|
171
|
+
|
172
|
+
The `Imlib2` library is mainly file-oriented and doesn't provide a way of loading
|
173
|
+
the undecoded image from a memory buffer. Therefore, the functionality is
|
174
|
+
implemented on the Ruby side of the gem, writing the memory buffer to a Tempfile.
|
175
|
+
Currently, this local write cannot be avoided.
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
image = Rszr::Image.load_data(binary_data)
|
179
|
+
|
180
|
+
data = image.save_data(format: :jpeg)
|
67
181
|
```
|
68
182
|
|
69
183
|
## Thread safety
|
70
184
|
|
71
|
-
As of version 0.
|
185
|
+
As of version 0.5.0, Rszr is thread safe through Ruby's global VM lock.
|
72
186
|
Use of any previous versions in a threaded environment is discouraged.
|
73
187
|
|
74
188
|
## Speed
|
75
189
|
|
76
|
-
Resizing
|
190
|
+
Resizing a 1500x997 JPEG image to 800x532, 500 times:
|
191
|
+
![Speed](https://github.com/mtgrosser/rszr/blob/master/benchmark/speed.png)
|
192
|
+
|
77
193
|
|
78
194
|
Library | Time
|
79
195
|
----------------|-----------
|
80
|
-
MiniMagick |
|
81
|
-
GD2 |
|
82
|
-
|
196
|
+
MiniMagick | 27.0 s
|
197
|
+
GD2 | 28.2 s
|
198
|
+
VIPS | 13.6 s
|
199
|
+
Rszr | 7.9 s
|
data/Rakefile
CHANGED
data/ext/rszr/errors.c
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#ifndef RUBY_RSZR_ERRORS
|
2
|
+
#define RUBY_RSZR_ERRORS
|
3
|
+
|
4
|
+
#include "rszr.h"
|
5
|
+
#include "errors.h"
|
6
|
+
|
7
|
+
VALUE eRszrError = Qnil;
|
8
|
+
VALUE eRszrFileNotFound = Qnil;
|
9
|
+
VALUE eRszrTransformationError = Qnil;
|
10
|
+
VALUE eRszrErrorWithMessage = Qnil;
|
11
|
+
VALUE eRszrLoadError = Qnil;
|
12
|
+
VALUE eRszrSaveError = Qnil;
|
13
|
+
|
14
|
+
static const char * const sRszrErrorMessages[] =
|
15
|
+
{
|
16
|
+
"File does not exist",
|
17
|
+
"File is a directory",
|
18
|
+
"Read permission denied",
|
19
|
+
"Unsupported format",
|
20
|
+
"Path too long",
|
21
|
+
"Non-existant path component",
|
22
|
+
"Path component is not a directory",
|
23
|
+
"Path outside address space",
|
24
|
+
"Too many symbolic links",
|
25
|
+
"Out of memory",
|
26
|
+
"Out of file descriptors",
|
27
|
+
"Write permission denied",
|
28
|
+
"Out of disk space",
|
29
|
+
"Unknown error"
|
30
|
+
};
|
31
|
+
const int RSZR_MAX_ERROR_INDEX = 13;
|
32
|
+
|
33
|
+
void Init_rszr_errors()
|
34
|
+
{
|
35
|
+
eRszrError = rb_define_class_under(mRszr, "Error", rb_eStandardError);
|
36
|
+
eRszrFileNotFound = rb_define_class_under(mRszr, "FileNotFound", eRszrError);
|
37
|
+
eRszrTransformationError = rb_define_class_under(mRszr, "TransformationError", eRszrError);
|
38
|
+
eRszrErrorWithMessage = rb_define_class_under(mRszr, "ErrorWithMessage", eRszrError);
|
39
|
+
eRszrLoadError = rb_define_class_under(mRszr, "LoadError", eRszrErrorWithMessage);
|
40
|
+
eRszrSaveError = rb_define_class_under(mRszr, "SaveError", eRszrErrorWithMessage);
|
41
|
+
}
|
42
|
+
|
43
|
+
static void rszr_raise_error_with_message(VALUE rb_error_class, Imlib_Load_Error error)
|
44
|
+
{
|
45
|
+
VALUE rb_error;
|
46
|
+
int error_index;
|
47
|
+
|
48
|
+
error_index = (int) error - 1;
|
49
|
+
|
50
|
+
if (error_index < 1 || error_index > RSZR_MAX_ERROR_INDEX)
|
51
|
+
error_index = RSZR_MAX_ERROR_INDEX;
|
52
|
+
|
53
|
+
rb_error = rb_exc_new2(rb_error_class, sRszrErrorMessages[error_index]);
|
54
|
+
rb_exc_raise(rb_error);
|
55
|
+
}
|
56
|
+
|
57
|
+
void rszr_raise_load_error(Imlib_Load_Error error)
|
58
|
+
{
|
59
|
+
rszr_raise_error_with_message(eRszrLoadError, error);
|
60
|
+
}
|
61
|
+
|
62
|
+
void rszr_raise_save_error(Imlib_Load_Error error)
|
63
|
+
{
|
64
|
+
rszr_raise_error_with_message(eRszrSaveError, error);
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
#endif
|
data/ext/rszr/errors.h
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef RUBY_RSZR_ERRORS_H
|
2
|
+
#define RUBY_RSZR_ERRORS_H
|
3
|
+
|
4
|
+
void Init_rszr_errors();
|
5
|
+
void rszr_raise_load_error(Imlib_Load_Error error);
|
6
|
+
void rszr_raise_save_error(Imlib_Load_Error error);
|
7
|
+
|
8
|
+
extern VALUE eRszrError;
|
9
|
+
extern VALUE eRszrFileNotFound;
|
10
|
+
extern VALUE eRszrTransformationError;
|
11
|
+
extern VALUE eRszrErrorWithMessage;
|
12
|
+
extern VALUE eRszrLoadError;
|
13
|
+
extern VALUE eRszrSaveError;
|
14
|
+
|
15
|
+
#endif
|
data/ext/rszr/extconf.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
imlib2_config = with_config('imlib2-config', 'imlib2-config')
|
5
|
+
|
6
|
+
$CFLAGS << ' -DX_DISPLAY_MISSING ' << `#{imlib2_config} --cflags`.chomp
|
7
|
+
$LDFLAGS << ' ' << `#{imlib2_config} --libs`.chomp
|
8
|
+
$LDFLAGS.gsub!(/\ -lX11\ -lXext/, '') if RUBY_PLATFORM =~ /darwin/
|
9
|
+
|
10
|
+
unless find_header('Imlib2.h')
|
11
|
+
abort 'imlib2 development headers are missing'
|
12
|
+
end
|
13
|
+
|
14
|
+
unless find_library('Imlib2', 'imlib_set_cache_size')
|
15
|
+
abort 'Imlib2 is missing'
|
16
|
+
end
|
17
|
+
|
18
|
+
create_makefile 'rszr/rszr'
|