dragonfly-lossless_rotate 0.1.1 → 0.1.2

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
  SHA256:
3
- metadata.gz: 980d9f58a025a965308c14d93100cf22bf293803ae7d7df58ef8ae484c50690b
4
- data.tar.gz: b7e6c1af2f809f227a84a5db967b5d0abfee1ae2f2098df9da626fd678fd216e
3
+ metadata.gz: 344be41ffd0ead843a69adc18b8161e08dab0fef2ffb8c1591607976ff01f2b2
4
+ data.tar.gz: a515cc697760c756aac4d2dfe770d42507f2948833de0d9623b6ee0a00b41845
5
5
  SHA512:
6
- metadata.gz: b8ca9e89edd39b58071e79cc297b698bd60493a7a649e785e015dfe2d8de87b05da9e785fc8d69e29470f76ff28fa3f11328d63c57b158e29c20ea8c04d5546e
7
- data.tar.gz: 4e3137e0458fcc1649df916dfd3459767e27859e85b743e721ebae6a8cc1e957b35b323f33eb3313f10c2a2acd822b01817e213b70358ce8d8c02673492d7ed4
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.290000 1.170000 9.600000 ( 10.321087)
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.450000 1.470000 23.610000 ( 25.478872)
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 | convert - -rotate 90 JPG:new_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.470000 1.110000 29.630000 ( 26.944807)
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.500000 1.810000 43.420000 ( 42.309805)
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 | convert - -rotate 90 JPG:new_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.270000 1.170000 31.300000 ( 28.983087)
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.340000 1.310000 44.890000 ( 43.052428)
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 ||= content.env[:libjpeg_optimize]
33
- progressive ||= content.env[:libjpeg_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
- output_command = if optimize
51
- " #{pnmflip_bin} -r#{pnmflip_degrees(degree)} | #{cjpeg_bin}#{progressive_option}#{optimize_option} > '#{new_path}'"
52
- else
53
- " convert - -rotate #{degree} 'JPG:#{new_path}'"
54
- end
55
-
56
- lossless_rotate_command = "#{jpegtran_bin} -rotate #{jpegtran_degrees(degree)} -perfect#{progressive_option}#{optimize_option} '#{old_path}' > '#{new_path}'"
57
- lossy_rotate_command = "#{djpeg_bin} '#{old_path}' |#{output_command}"
58
-
59
- "#{lossless_rotate_command} || #{lossy_rotate_command}"
60
- end
61
- end
62
-
63
- def pnmflip_degrees(degree)
64
- {
65
- 90 => 270,
66
- 180 => 180,
67
- 270 => 90,
68
- -90 => 90,
69
- -180 => 180,
70
- -270 => 270
71
- }[degree]
72
- end
73
-
74
- def jpegtran_degrees(degree)
75
- {
76
- 90 => 90,
77
- 180 => 180,
78
- 270 => 180,
79
- -90 => 270,
80
- -180 => 180,
81
- -270 => 90
82
- }[degree]
83
- end
84
-
85
- def jpeg?(content)
86
- content.shell_eval { |path| "identify -format \%m #{path}" } == "JPEG"
87
- end
88
- end
89
-
90
- # All formats support by ImageMagick
91
- class SafeRotate < Rotate
92
- def rotate(content, degree, optimize, progressive)
93
- return super if jpeg?(content)
94
-
95
- content.shell_update do |old_path, new_path|
96
- "convert #{old_path} -rotate #{degree} #{new_path}"
97
- end
98
- end
99
- private :rotate
100
- end
101
- end
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dragonfly
4
4
  class LosslessRotate
5
- VERSION = "0.1.1"
5
+ VERSION = "0.1.2"
6
6
  end
7
7
  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.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-15 00:00:00.000000000 Z
11
+ date: 2018-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dragonfly