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 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