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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6ab5d9447d5919f0bed35e0562f7645bb5a23db
4
- data.tar.gz: 88988dc45c31575db6a1cf11618298be6641fca8
3
+ metadata.gz: 035d5f7341e71cdc9b5ba70de6e116acd8d8459e
4
+ data.tar.gz: 3119e97a26295db8f3931821d6ae835aaa6166ee
5
5
  SHA512:
6
- metadata.gz: 4a5d7d5ba83088cce7de9af7a0d68c92d2e2c0f58029617dfa1c270a83aa58af96168b11b2bebdd0c3ad1a930598726acd0809b5b3a7dea901567402bf23ed1b
7
- data.tar.gz: 1a53df4fcbd02f524d42cfadcd9dbacdba3945423f5a244af8da190e4cc59de2b87b267de78b0481c4c8d106d27dc16a2ec30f4f728310eced9e9da8a0191f0f
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) [![Build Status](https://travis-ci.org/mtgrosser/rszr.svg)](https://travis-ci.org/mtgrosser/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. It is faster and consumes less memory than MiniMagick, rmagick and GD2.
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
- # image dimensions
64
- image.width => 400
65
- image.height => 300
66
- image.dimensions => [400, 300]
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.4.0, Rszr provides thread safety by synchronizing access to imlib2 function calls.
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 an 1500x997 JPEG image to 800x532, 100 times:
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 | 12.9 s
81
- GD2 | 7.5 s
82
- Rszr | 2.8 s
196
+ MiniMagick | 27.0 s
197
+ GD2 | 28.2 s
198
+ VIPS | 13.6 s
199
+ Rszr | 7.9 s
data/Rakefile CHANGED
@@ -9,3 +9,9 @@ begin
9
9
  rescue LoadError
10
10
  # no rspec available
11
11
  end
12
+
13
+ require 'rake/extensiontask'
14
+
15
+ Rake::ExtensionTask.new('rszr') do |ext|
16
+ ext.lib_dir = 'lib/rszr'
17
+ end
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
@@ -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'