dragonfly-lossless_rotate 0.1.0 → 0.1.1

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: 4570113d02eed8571af6ccd48135730ecb435d85edc5db4f3c12dc5134fbb4c0
4
- data.tar.gz: 1c711083d0e1a89a0f13ade6e1d30488f4f565aaefda54fcde30c73b356e4b94
3
+ metadata.gz: 980d9f58a025a965308c14d93100cf22bf293803ae7d7df58ef8ae484c50690b
4
+ data.tar.gz: b7e6c1af2f809f227a84a5db967b5d0abfee1ae2f2098df9da626fd678fd216e
5
5
  SHA512:
6
- metadata.gz: 83923e26bc11d4cab7cbf1dfc30f1a81528917ff5454d5636eeb0d8a9920454639a6fa74c94820b84e804da5aa3ffd3ffa6c63c033284fd90ce839be8291743a
7
- data.tar.gz: 8dd6253e9ac9f9766439c87f26c285c0f8be8bfc1d7bba6ba92ca92b773cb5ab72d4b611f914425839d24ce62d4486643c477b9ad82a9262dab2edd275b3fc10
6
+ metadata.gz: b8ca9e89edd39b58071e79cc297b698bd60493a7a649e785e015dfe2d8de87b05da9e785fc8d69e29470f76ff28fa3f11328d63c57b158e29c20ea8c04d5546e
7
+ data.tar.gz: 4e3137e0458fcc1649df916dfd3459767e27859e85b743e721ebae6a8cc1e957b35b323f33eb3313f10c2a2acd822b01817e213b70358ce8d8c02673492d7ed4
@@ -0,0 +1,169 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+ # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
4
+ # to ignore them, so only the ones explicitly set in this file are enabled.
5
+ DisabledByDefault: true
6
+ Exclude:
7
+ - '**/templates/**/*'
8
+ - '**/vendor/**/*'
9
+ - 'actionpack/lib/action_dispatch/journey/parser.rb'
10
+ - 'railties/test/fixtures/tmp/**/*'
11
+
12
+ # Prefer &&/|| over and/or.
13
+ Style/AndOr:
14
+ Enabled: true
15
+
16
+ # Do not use braces for hash literals when they are the last argument of a
17
+ # method call.
18
+ Style/BracesAroundHashParameters:
19
+ Enabled: true
20
+ EnforcedStyle: context_dependent
21
+
22
+ # Align `when` with `case`.
23
+ Layout/CaseIndentation:
24
+ Enabled: true
25
+
26
+ # Align comments with method definitions.
27
+ Layout/CommentIndentation:
28
+ Enabled: true
29
+
30
+ Layout/ElseAlignment:
31
+ Enabled: true
32
+
33
+ # Align `end` with the matching keyword or starting expression except for
34
+ # assignments, where it should be aligned with the LHS.
35
+ Layout/EndAlignment:
36
+ Enabled: true
37
+ EnforcedStyleAlignWith: variable
38
+ AutoCorrect: true
39
+
40
+ Layout/EmptyLineAfterMagicComment:
41
+ Enabled: true
42
+
43
+ Layout/EmptyLinesAroundBlockBody:
44
+ Enabled: true
45
+
46
+ # In a regular class definition, no empty lines around the body.
47
+ Layout/EmptyLinesAroundClassBody:
48
+ Enabled: true
49
+
50
+ # In a regular method definition, no empty lines around the body.
51
+ Layout/EmptyLinesAroundMethodBody:
52
+ Enabled: true
53
+
54
+ # In a regular module definition, no empty lines around the body.
55
+ Layout/EmptyLinesAroundModuleBody:
56
+ Enabled: true
57
+
58
+ Layout/FirstParameterIndentation:
59
+ Enabled: true
60
+
61
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
62
+ Style/HashSyntax:
63
+ Enabled: true
64
+
65
+ # Method definitions after `private` or `protected` isolated calls need one
66
+ # extra level of indentation.
67
+ Layout/IndentationConsistency:
68
+ Enabled: true
69
+ EnforcedStyle: rails
70
+
71
+ # Two spaces, no tabs (for indentation).
72
+ Layout/IndentationWidth:
73
+ Enabled: true
74
+
75
+ Layout/LeadingCommentSpace:
76
+ Enabled: true
77
+
78
+ Layout/SpaceAfterColon:
79
+ Enabled: true
80
+
81
+ Layout/SpaceAfterComma:
82
+ Enabled: true
83
+
84
+ Layout/SpaceAroundEqualsInParameterDefault:
85
+ Enabled: true
86
+
87
+ Layout/SpaceAroundKeyword:
88
+ Enabled: true
89
+
90
+ Layout/SpaceAroundOperators:
91
+ Enabled: true
92
+
93
+ Layout/SpaceBeforeComma:
94
+ Enabled: true
95
+
96
+ Layout/SpaceBeforeFirstArg:
97
+ Enabled: true
98
+
99
+ Style/DefWithParentheses:
100
+ Enabled: true
101
+
102
+ # Defining a method with parameters needs parentheses.
103
+ Style/MethodDefParentheses:
104
+ Enabled: true
105
+
106
+ Style/FrozenStringLiteralComment:
107
+ Enabled: true
108
+ EnforcedStyle: always
109
+ Exclude:
110
+ - 'actionview/test/**/*.builder'
111
+ - 'actionview/test/**/*.ruby'
112
+ - 'actionpack/test/**/*.builder'
113
+ - 'actionpack/test/**/*.ruby'
114
+ - 'activestorage/db/migrate/**/*.rb'
115
+
116
+ # Use `foo {}` not `foo{}`.
117
+ Layout/SpaceBeforeBlockBraces:
118
+ Enabled: true
119
+
120
+ # Use `foo { bar }` not `foo {bar}`.
121
+ Layout/SpaceInsideBlockBraces:
122
+ Enabled: true
123
+
124
+ # Use `{ a: 1 }` not `{a:1}`.
125
+ Layout/SpaceInsideHashLiteralBraces:
126
+ Enabled: true
127
+
128
+ Layout/SpaceInsideParens:
129
+ Enabled: true
130
+
131
+ # Check quotes usage according to lint rule below.
132
+ Style/StringLiterals:
133
+ Enabled: true
134
+ EnforcedStyle: double_quotes
135
+
136
+ # Detect hard tabs, no hard tabs.
137
+ Layout/Tab:
138
+ Enabled: true
139
+
140
+ # Blank lines should not have any spaces.
141
+ Layout/TrailingBlankLines:
142
+ Enabled: true
143
+
144
+ # No trailing whitespace.
145
+ Layout/TrailingWhitespace:
146
+ Enabled: true
147
+
148
+ # Use quotes for string literals when they are enough.
149
+ Style/UnneededPercentQ:
150
+ Enabled: true
151
+
152
+ # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
153
+ Lint/RequireParentheses:
154
+ Enabled: true
155
+
156
+ Lint/StringConversionInInterpolation:
157
+ Enabled: true
158
+
159
+ Style/RedundantReturn:
160
+ Enabled: true
161
+ AllowMultipleReturnValues: true
162
+
163
+ Style/Semicolon:
164
+ Enabled: true
165
+ AllowAsExpressionSeparator: true
166
+
167
+ # Prefer Foo.method over Foo::method
168
+ Style/ColonMethodCall:
169
+ Enabled: true
data/README.md CHANGED
@@ -49,9 +49,6 @@ JPEG only:
49
49
  @image.process(:lossless_rotate, 180)
50
50
  @image.process(:lossless_rotate, 270)
51
51
  @image.process(:lossless_rotate, -90)
52
-
53
- # Without JPEG optimization
54
- @image.process(:lossless_rotate, 90, optimize: false)
55
52
  ```
56
53
 
57
54
  With fallback for other formats (rotate via ImageMagick):
@@ -59,6 +56,19 @@ With fallback for other formats (rotate via ImageMagick):
59
56
  @image.process(:safe_lossless_rotate)
60
57
  ```
61
58
 
59
+ Other options:
60
+ ```ruby
61
+ # Without JPEG optimization (default: true)
62
+ @image.process(:lossless_rotate, 90, optimize: false)
63
+ # Set default value
64
+ plugin :lossless_rotate, libjpeg_optimize: false
65
+
66
+ # Create progressive JPEG file (default: false)
67
+ @image.process(:lossless_rotate, 90, progressive: true)
68
+ # Set default value
69
+ plugin :lossless_rotate, libjpeg_progressive: true
70
+ ```
71
+
62
72
  ## Benchmark
63
73
 
64
74
  - _libjpeg_ version 9b (17-Jan-2016)
@@ -1,23 +1,25 @@
1
- lib = File.expand_path("lib", __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "dragonfly/lossless_rotate/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "dragonfly-lossless_rotate"
7
- spec.version = Dragonfly::LosslessRotate::VERSION
8
- spec.summary = "Dragonfly lossless image rotate"
9
- spec.description = "Lossless rotating and compressing JPEG images via libjpeg tools"
10
- spec.author = "Maxim Perepelitsa"
11
- spec.email = "n0xff@outlook.com"
12
- spec.homepage = "https://github.com/n0xff/dragonfly-lossless_rotate"
13
- spec.license = "MIT"
14
-
15
- spec.requirements << "cjpeg"
16
- spec.requirements << "djpeg"
17
- spec.requirements << "jpegtran"
18
- spec.requirements << "pnmflip"
19
-
20
- spec.files = `git ls-files`.split($/)
21
-
22
- spec.add_runtime_dependency "dragonfly", "~> 1.0"
23
- end
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "dragonfly/lossless_rotate/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "dragonfly-lossless_rotate"
9
+ spec.version = Dragonfly::LosslessRotate::VERSION
10
+ spec.summary = "Dragonfly lossless image rotate"
11
+ spec.description = "Lossless rotating and compressing JPEG images via libjpeg tools"
12
+ spec.author = "Maxim Perepelitsa"
13
+ spec.email = "n0xff@outlook.com"
14
+ spec.homepage = "https://github.com/n0xff/dragonfly-lossless_rotate"
15
+ spec.license = "MIT"
16
+
17
+ spec.requirements << "cjpeg"
18
+ spec.requirements << "djpeg"
19
+ spec.requirements << "jpegtran"
20
+ spec.requirements << "pnmflip"
21
+
22
+ spec.files = `git ls-files`.split($/)
23
+
24
+ spec.add_runtime_dependency "dragonfly", "~> 1.0"
25
+ end
@@ -1,93 +1,102 @@
1
- require "dragonfly"
2
-
3
- Dragonfly::App.register_plugin(:lossless_rotate) { Dragonfly::LosslessRotate::Plugin.new }
4
-
5
- module Dragonfly
6
- class LosslessRotate
7
-
8
- class Plugin
9
- def call(app, opts={})
10
- app.env[:cjpeg_bin] = opts[:cjpeg_bin] || "cjpeg"
11
- app.env[:djpeg_bin] = opts[:djpeg_bin] || "djpeg"
12
- app.env[:jpegtran_bin] = opts[:jpegtran_bin] || "jpegtran"
13
- app.env[:pnmflip_bin] = opts[:pnmflip_bin] || "pnmflip"
14
-
15
- app.add_processor :lossless_rotate, Dragonfly::LosslessRotate::Rotate.new
16
- app.add_processor :safe_lossless_rotate, Dragonfly::LosslessRotate::SafeRotate.new
17
- end
18
- end
19
-
20
- # Only JPEG format
21
- class Rotate
22
- def call(content, degree=90, optimize: true)
23
- unless [90, 180, 270, -90, -180, -270].include?(degree)
24
- warn "Rotate by 90, 180 and 270 degrees allowed"
25
- degree = 90
26
- end
27
-
28
- rotate(content, degree, optimize)
29
- end
30
-
31
- private
32
-
33
- def rotate(content, degree, optimize)
34
- cjpeg_bin = content.env[:cjpeg_bin] || "cjpeg"
35
- djpeg_bin = content.env[:djpeg_bin] || "djpeg"
36
- jpegtran_bin = content.env[:jpegtran_bin] || "jpegtran"
37
- pnmflip_bin = content.env[:pnmflip_bin] || "pnmflip"
38
-
39
- content.shell_update escape: false do |old_path, new_path|
40
- optimize_option = " -optimize" if optimize
41
- output_command = if optimize
42
- " #{pnmflip_bin} -r#{pnmflip_degrees(degree)} | #{cjpeg_bin}#{optimize_option} > #{new_path}"
43
- else
44
- " convert - -rotate #{degree} JPG:#{new_path}"
45
- end
46
-
47
- lossless_rotate_command = "#{jpegtran_bin} -rotate #{jpegtran_degrees(degree)} -perfect#{optimize_option} #{old_path} > #{new_path}"
48
- lossy_rotate_command = "#{djpeg_bin} #{old_path} |#{output_command}"
49
-
50
- "#{lossless_rotate_command} || #{lossy_rotate_command}"
51
- end
52
- end
53
-
54
- def pnmflip_degrees(degree)
55
- {
56
- 90 => 270,
57
- 180 => 180,
58
- 270 => 90,
59
- -90 => 90,
60
- -180 => 180,
61
- -270 => 270
62
- }[degree]
63
- end
64
-
65
- def jpegtran_degrees(degree)
66
- {
67
- 90 => 90,
68
- 180 => 180,
69
- 270 => 180,
70
- -90 => 270,
71
- -180 => 180,
72
- -270 => 90
73
- }[degree]
74
- end
75
-
76
- def jpeg?(content)
77
- content.shell_eval { |path| "identify -format \%m #{path}" } == "JPEG"
78
- end
79
- end
80
-
81
- # All formats support by ImageMagick
82
- class SafeRotate < Rotate
83
- def rotate(content, degree, optimize)
84
- return super if jpeg?(content)
85
-
86
- content.shell_update escape: false do |old_path, new_path|
87
- "convert -rotate #{degree} #{old_path} > #{new_path}"
88
- end
89
- end
90
- private :rotate
91
- end
92
- end
93
- 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]
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,5 +1,7 @@
1
- module Dragonfly
2
- class LosslessRotate
3
- VERSION = "0.1.0"
4
- end
5
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Dragonfly
4
+ class LosslessRotate
5
+ VERSION = "0.1.1"
6
+ end
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dragonfly-lossless_rotate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Perepelitsa
@@ -30,6 +30,7 @@ executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
+ - ".rubocop.yml"
33
34
  - README.md
34
35
  - dragonfly-lossless_rotate.gemspec
35
36
  - lib/dragonfly/lossless_rotate.rb