dragonfly-lossless_rotate 0.1.1 → 0.1.2
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 +4 -4
- data/README.md +8 -63
- data/lib/dragonfly/lossless_rotate.rb +101 -102
- data/lib/dragonfly/lossless_rotate/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 344be41ffd0ead843a69adc18b8161e08dab0fef2ffb8c1591607976ff01f2b2
|
4
|
+
data.tar.gz: a515cc697760c756aac4d2dfe770d42507f2948833de0d9623b6ee0a00b41845
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82c2acf9d420d436f6f356674de868247176401c51c6ba9b0a7225115b25078b1a50c564d6e7ae99e4ece9dd11e39e1f8a50f7faa101d424364d17db98daf5f7
|
7
|
+
data.tar.gz: 8cc2b9bad7e9769e5559a9cb3ac1259ef2676e189ea30265e95b7869b5b207f103a1f30e690b9258b0e6882263a193775e357dfe66ac42f61f5c4072264f9fa5
|
data/README.md
CHANGED
@@ -71,7 +71,6 @@ plugin :lossless_rotate, libjpeg_progressive: true
|
|
71
71
|
|
72
72
|
## Benchmark
|
73
73
|
|
74
|
-
- _libjpeg_ version 9b (17-Jan-2016)
|
75
74
|
- _libjpeg-turbo_ version 1.4.2 (build 20160222)
|
76
75
|
- _MozJPEG_ version 3.3.2 (build 20180713)
|
77
76
|
|
@@ -88,34 +87,6 @@ puts Benchmark.measure { 500.times { @image.rotate(90).apply } }
|
|
88
87
|
|
89
88
|
### Lossless rotate
|
90
89
|
|
91
|
-
#### libjpeg
|
92
|
-
|
93
|
-
##### (optimize=true)
|
94
|
-
```bash
|
95
|
-
jpegtran -rotate 90 -perfect -optimize old_path > new_path
|
96
|
-
```
|
97
|
-
|
98
|
-
```ruby
|
99
|
-
puts Benchmark.measure { 500.times { @image.process(:lossless_rotate).apply } }
|
100
|
-
0.240000 1.190000 10.600000 ( 11.368903)
|
101
|
-
|
102
|
-
puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate).apply } }
|
103
|
-
0.440000 1.640000 24.360000 ( 26.211808)
|
104
|
-
```
|
105
|
-
|
106
|
-
##### (optimize=false)
|
107
|
-
```bash
|
108
|
-
jpegtran -rotate 90 -perfect old_path > new_path
|
109
|
-
```
|
110
|
-
|
111
|
-
```ruby
|
112
|
-
puts Benchmark.measure { 500.times { @image.process(:lossless_rotate, 90, optimize: false).apply } }
|
113
|
-
0.290000 1.170000 9.600000 ( 10.321087)
|
114
|
-
|
115
|
-
puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate, 90, optimize: false).apply } }
|
116
|
-
0.450000 1.470000 23.610000 ( 25.478872)
|
117
|
-
```
|
118
|
-
|
119
90
|
#### libjpeg-turbo
|
120
91
|
|
121
92
|
##### (optimize=true)
|
@@ -138,10 +109,10 @@ jpegtran -rotate 90 -perfect old_path > new_path
|
|
138
109
|
|
139
110
|
```ruby
|
140
111
|
puts Benchmark.measure { 500.times { @image.process(:lossless_rotate, 90, optimize: false).apply } }
|
141
|
-
0.
|
112
|
+
0.250000 1.090000 8.110000 ( 8.601707)
|
142
113
|
|
143
114
|
puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate, 90, optimize: false).apply } }
|
144
|
-
0.
|
115
|
+
0.360000 1.170000 21.480000 ( 22.744040)
|
145
116
|
```
|
146
117
|
|
147
118
|
#### MozJPEG
|
@@ -178,32 +149,6 @@ puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate, 90, o
|
|
178
149
|
|
179
150
|
Same image but resized to 556x417px
|
180
151
|
|
181
|
-
#### libjpeg
|
182
|
-
|
183
|
-
##### (optimize=true)
|
184
|
-
```bash
|
185
|
-
djpeg old_path | pnmflip -r270 | cjpeg -optimize > new_path
|
186
|
-
```
|
187
|
-
```ruby
|
188
|
-
puts Benchmark.measure { 500.times { @image.process(:lossless_rotate).apply } }
|
189
|
-
0.340000 0.930000 19.320000 ( 16.055059)
|
190
|
-
|
191
|
-
puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate).apply } }
|
192
|
-
0.390000 1.240000 32.520000 ( 30.055926)
|
193
|
-
```
|
194
|
-
|
195
|
-
##### (optimize=false)
|
196
|
-
```bash
|
197
|
-
djpeg old_path | convert - -rotate 90 JPG:new_path
|
198
|
-
```
|
199
|
-
```ruby
|
200
|
-
puts Benchmark.measure { 500.times { @image.process(:lossless_rotate, 90, optimize: false).apply } }
|
201
|
-
0.310000 1.450000 30.520000 ( 28.357557)
|
202
|
-
|
203
|
-
puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate, 90, optimize: false).apply } }
|
204
|
-
0.530000 1.520000 43.790000 ( 41.732961)
|
205
|
-
```
|
206
|
-
|
207
152
|
#### libjpeg-turbo
|
208
153
|
|
209
154
|
##### (optimize=true)
|
@@ -220,14 +165,14 @@ puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate).apply
|
|
220
165
|
|
221
166
|
##### (optimize=false)
|
222
167
|
```bash
|
223
|
-
djpeg old_path |
|
168
|
+
djpeg old_path | pnmflip -r270 | cjpeg > new_path
|
224
169
|
```
|
225
170
|
```ruby
|
226
171
|
puts Benchmark.measure { 500.times { @image.process(:lossless_rotate, 90, optimize: false).apply } }
|
227
|
-
0.
|
172
|
+
0.330000 1.250000 15.190000 ( 11.990070)
|
228
173
|
|
229
174
|
puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate, 90, optimize: false).apply } }
|
230
|
-
0.
|
175
|
+
0.330000 1.330000 29.010000 ( 26.816061)
|
231
176
|
```
|
232
177
|
|
233
178
|
#### MozJPEG
|
@@ -246,12 +191,12 @@ puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate).apply
|
|
246
191
|
|
247
192
|
##### (optimize=false)
|
248
193
|
```bash
|
249
|
-
mozjpeg-djpeg old_path |
|
194
|
+
mozjpeg-djpeg old_path | pnmflip -r270 | mozjpeg-cjpeg > new_path
|
250
195
|
```
|
251
196
|
```ruby
|
252
197
|
puts Benchmark.measure { 500.times { @image.process(:lossless_rotate, 90, optimize: false).apply } }
|
253
|
-
0.
|
198
|
+
0.240000 0.860000 40.550000 ( 38.247647)
|
254
199
|
|
255
200
|
puts Benchmark.measure { 500.times { @image.process(:safe_lossless_rotate, 90, optimize: false).apply } }
|
256
|
-
0.
|
201
|
+
0.480000 1.330000 54.550000 ( 52.941735)
|
257
202
|
```
|
@@ -1,102 +1,101 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dragonfly"
|
4
|
-
|
5
|
-
Dragonfly::App.register_plugin(:lossless_rotate) { Dragonfly::LosslessRotate::Plugin.new }
|
6
|
-
|
7
|
-
module Dragonfly
|
8
|
-
class LosslessRotate
|
9
|
-
class Plugin
|
10
|
-
def call(app, opts = {})
|
11
|
-
app.env[:cjpeg_bin] = opts[:cjpeg_bin] || "cjpeg"
|
12
|
-
app.env[:djpeg_bin] = opts[:djpeg_bin] || "djpeg"
|
13
|
-
app.env[:jpegtran_bin] = opts[:jpegtran_bin] || "jpegtran"
|
14
|
-
app.env[:pnmflip_bin] = opts[:pnmflip_bin] || "pnmflip"
|
15
|
-
|
16
|
-
app.env[:libjpeg_optimize] = opts[:libjpeg_optimize] || true
|
17
|
-
app.env[:libjpeg_progressive] = opts[:libjpeg_progressive] || false
|
18
|
-
|
19
|
-
app.add_processor :lossless_rotate, Dragonfly::LosslessRotate::Rotate.new
|
20
|
-
app.add_processor :safe_lossless_rotate, Dragonfly::LosslessRotate::SafeRotate.new
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Only JPEG format
|
25
|
-
class Rotate
|
26
|
-
def call(content, degree = 90, optimize: nil, progressive: nil)
|
27
|
-
unless [90, 180, 270, -90, -180, -270].include?(degree)
|
28
|
-
warn "Rotate only by 90, 180 and 270 degrees allowed"
|
29
|
-
degree = 90
|
30
|
-
end
|
31
|
-
|
32
|
-
optimize
|
33
|
-
progressive
|
34
|
-
|
35
|
-
rotate(content, degree, optimize, progressive)
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def rotate(content, degree, optimize, progressive)
|
41
|
-
cjpeg_bin = content.env[:cjpeg_bin] || "cjpeg"
|
42
|
-
djpeg_bin = content.env[:djpeg_bin] || "djpeg"
|
43
|
-
jpegtran_bin = content.env[:jpegtran_bin] || "jpegtran"
|
44
|
-
pnmflip_bin = content.env[:pnmflip_bin] || "pnmflip"
|
45
|
-
|
46
|
-
content.shell_update escape: false do |old_path, new_path|
|
47
|
-
optimize_option = " -optimize" if optimize
|
48
|
-
progressive_option = " -progressive" if progressive
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
-
|
69
|
-
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
-
|
80
|
-
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dragonfly"
|
4
|
+
|
5
|
+
Dragonfly::App.register_plugin(:lossless_rotate) { Dragonfly::LosslessRotate::Plugin.new }
|
6
|
+
|
7
|
+
module Dragonfly
|
8
|
+
class LosslessRotate
|
9
|
+
class Plugin
|
10
|
+
def call(app, opts = {})
|
11
|
+
app.env[:cjpeg_bin] = opts[:cjpeg_bin] || "cjpeg"
|
12
|
+
app.env[:djpeg_bin] = opts[:djpeg_bin] || "djpeg"
|
13
|
+
app.env[:jpegtran_bin] = opts[:jpegtran_bin] || "jpegtran"
|
14
|
+
app.env[:pnmflip_bin] = opts[:pnmflip_bin] || "pnmflip"
|
15
|
+
|
16
|
+
app.env[:libjpeg_optimize] = opts[:libjpeg_optimize] || true
|
17
|
+
app.env[:libjpeg_progressive] = opts[:libjpeg_progressive] || false
|
18
|
+
|
19
|
+
app.add_processor :lossless_rotate, Dragonfly::LosslessRotate::Rotate.new
|
20
|
+
app.add_processor :safe_lossless_rotate, Dragonfly::LosslessRotate::SafeRotate.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Only JPEG format
|
25
|
+
class Rotate
|
26
|
+
def call(content, degree = 90, optimize: nil, progressive: nil)
|
27
|
+
unless [90, 180, 270, -90, -180, -270].include?(degree)
|
28
|
+
warn "Rotate only by 90, 180 and 270 degrees allowed"
|
29
|
+
degree = 90
|
30
|
+
end
|
31
|
+
|
32
|
+
optimize = content.env[:libjpeg_optimize] if optimize.nil?
|
33
|
+
progressive = content.env[:libjpeg_progressive] if progressive.nil?
|
34
|
+
|
35
|
+
rotate(content, degree, optimize, progressive)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def rotate(content, degree, optimize, progressive)
|
41
|
+
cjpeg_bin = content.env[:cjpeg_bin] || "cjpeg"
|
42
|
+
djpeg_bin = content.env[:djpeg_bin] || "djpeg"
|
43
|
+
jpegtran_bin = content.env[:jpegtran_bin] || "jpegtran"
|
44
|
+
pnmflip_bin = content.env[:pnmflip_bin] || "pnmflip"
|
45
|
+
|
46
|
+
content.shell_update escape: false do |old_path, new_path|
|
47
|
+
optimize_option = " -optimize" if optimize
|
48
|
+
progressive_option = " -progressive" if progressive
|
49
|
+
|
50
|
+
lossless_rotate_command = "#{jpegtran_bin} -rotate #{jpegtran_degrees(degree)} -perfect#{progressive_option}#{optimize_option} '#{old_path}' > '#{new_path}'"
|
51
|
+
|
52
|
+
decompress_command = " #{djpeg_bin} '#{old_path}'"
|
53
|
+
pnmflip_command = " #{pnmflip_bin} -r#{pnmflip_degrees(degree)}"
|
54
|
+
cjpeg_command = " #{cjpeg_bin}#{progressive_option}#{optimize_option} > '#{new_path}'"
|
55
|
+
|
56
|
+
lossy_rotate_command = "#{decompress_command} |#{pnmflip_command} |#{cjpeg_command}"
|
57
|
+
|
58
|
+
"#{lossless_rotate_command} ||#{lossy_rotate_command}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def pnmflip_degrees(degree)
|
63
|
+
{
|
64
|
+
90 => 270,
|
65
|
+
180 => 180,
|
66
|
+
270 => 90,
|
67
|
+
-90 => 90,
|
68
|
+
-180 => 180,
|
69
|
+
-270 => 270
|
70
|
+
}[degree]
|
71
|
+
end
|
72
|
+
|
73
|
+
def jpegtran_degrees(degree)
|
74
|
+
{
|
75
|
+
90 => 90,
|
76
|
+
180 => 180,
|
77
|
+
270 => 180,
|
78
|
+
-90 => 270,
|
79
|
+
-180 => 180,
|
80
|
+
-270 => 90
|
81
|
+
}[degree]
|
82
|
+
end
|
83
|
+
|
84
|
+
def jpeg?(content)
|
85
|
+
content.shell_eval { |path| "identify -format \%m #{path}" } == "JPEG"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# All formats support by ImageMagick
|
90
|
+
class SafeRotate < Rotate
|
91
|
+
def rotate(content, degree, optimize, progressive)
|
92
|
+
return super if jpeg?(content)
|
93
|
+
|
94
|
+
content.shell_update do |old_path, new_path|
|
95
|
+
"convert #{old_path} -rotate #{degree} #{new_path}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
private :rotate
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dragonfly-lossless_rotate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maxim Perepelitsa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dragonfly
|