image_processing 1.7.1 → 1.8.0

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: a29aea1a51fb4462e6ac812af95fe95ca5b07636985604e63e88cade5391bd36
4
- data.tar.gz: 9f0413d75de435951048d7086264add8a8bf904936d668bfb9f2d1677bb24c64
3
+ metadata.gz: f22578c76658031df98eee4b527240f093f67685fe500203133cc0926c98651a
4
+ data.tar.gz: 00a25b55f2ac02e1ba2f9fa680df72bd686a6e364474b734673f30c28673df02
5
5
  SHA512:
6
- metadata.gz: 745f44c113464999228dd8138b5a3935e6a9002c994414af64d0cb3bbd418303a005d370c6ed54ea738630b260094fd48dda33d91ee32b721a57f2c43e651d35
7
- data.tar.gz: 51e325b7fd7c94a347e00f97d73712066fe09ee32ebf39947e432ad726cd2e50c4a4ec43005989bd83a00055b30cb249cf31000b19dd48de0ab8ee286bc7efd3
6
+ metadata.gz: dd79bd00804d9c2dde5e51d0fffe6e48cdd3ee5d69333cbe4a5471ce3714c0be43b4cf39df7d464fe7b23d76c172c417612de37a50d3173f2bffc130eac5498e
7
+ data.tar.gz: 0f13da9ed2363bc7f763f5ad73be4e6981344879472747905e57aa48eb0bce9fc261b39f6168ed8ce679fc5da70270321302858ba50df1a7362a899f6fceee59
@@ -1,150 +1,154 @@
1
+ ## 1.8.0 (2019-02-25)
2
+
3
+ * [vips] Perform resize-on-load when possible, significantly improving resizing speed (@janko)
4
+
1
5
  ## 1.7.1 (2018-09-27)
2
6
 
3
- * [vips] Make `#remove` that's used for removing image metadata chainable (@janko-m)
7
+ * [vips] Make `#remove` that's used for removing image metadata chainable (@janko)
4
8
 
5
9
  ## 1.7.0 (2018-09-20)
6
10
 
7
- * [vips] `#rotate` now always calls `vips_similarity()` and forwards all options to it (@janko-m)
11
+ * [vips] `#rotate` now always calls `vips_similarity()` and forwards all options to it (@janko)
8
12
 
9
13
  ## 1.6.0 (2018-07-13)
10
14
 
11
- * [vips] In `#composite` accept `:offset` option for the position of the overlay image (@janko-m)
15
+ * [vips] In `#composite` accept `:offset` option for the position of the overlay image (@janko)
12
16
 
13
- * [vips] In `#composite` accept `:gravity` option for the direction of the overlay image (@janko-m)
17
+ * [vips] In `#composite` accept `:gravity` option for the direction of the overlay image (@janko)
14
18
 
15
- * [vips] In `#composite` accept blend mode as an optional `:mode` parameter which defaults to `:over` (@janko-m)
19
+ * [vips] In `#composite` accept blend mode as an optional `:mode` parameter which defaults to `:over` (@janko)
16
20
 
17
- * [minimagick] In `#composite` rename `:compose` option to `:mode` (@janko-m)
21
+ * [minimagick] In `#composite` rename `:compose` option to `:mode` (@janko)
18
22
 
19
- * [minimagick] In `#composite` replace `:geometry` option with `:offset` which accepts an array (@janko-m)
23
+ * [minimagick] In `#composite` replace `:geometry` option with `:offset` which accepts an array (@janko)
20
24
 
21
25
  ## 1.5.0 (2018-07-10)
22
26
 
23
- * [minimagick, vips] Add `#composite` method (@janko-m)
27
+ * [minimagick, vips] Add `#composite` method (@janko)
24
28
 
25
29
  * [core] Allow operations to accept blocks (janko-m)
26
30
 
27
31
  ## 1.4.0 (2018-06-14)
28
32
 
29
- * [minimagick] Accept RGB(A) arrays for color names for `:background` (@janko-m)
33
+ * [minimagick] Accept RGB(A) arrays for color names for `:background` (@janko)
30
34
 
31
- * [minimagick] Don't add empty `-background` option in `#rotate` when `:background` is not given (@janko-m)
35
+ * [minimagick] Don't add empty `-background` option in `#rotate` when `:background` is not given (@janko)
32
36
 
33
- * [vips] Modify `#rotate` to accept only `:background` and not other `vips_similarity()` options (@janko-m)
37
+ * [vips] Modify `#rotate` to accept only `:background` and not other `vips_similarity()` options (@janko)
34
38
 
35
39
  ## 1.3.0 (2018-06-13)
36
40
 
37
- * [minimagick, vips] Add `#rotate` method (@janko-m)
41
+ * [minimagick, vips] Add `#rotate` method (@janko)
38
42
 
39
- * [vips] Use native `vips_image_hasalpha()` and `vips_addalpha()` functions in `#resize_and_pad` (@janko-m)
43
+ * [vips] Use native `vips_image_hasalpha()` and `vips_addalpha()` functions in `#resize_and_pad` (@janko)
40
44
 
41
45
  ## 1.2.0 (2018-04-18)
42
46
 
43
- * [minimagick] Allow appending "+" operators in `#loader` and `#saver` using the value `false` (@janko-m)
47
+ * [minimagick] Allow appending "+" operators in `#loader` and `#saver` using the value `false` (@janko)
44
48
 
45
- * [core] Fix `#apply` not accepting a Hash as an argument (@janko-m)
49
+ * [core] Fix `#apply` not accepting a Hash as an argument (@janko)
46
50
 
47
- * [core] Allow sending any builder commands via `#apply`, not just operations (@janko-m)
51
+ * [core] Allow sending any builder commands via `#apply`, not just operations (@janko)
48
52
 
49
- * [minimagick] Add `#define` as a wrapper around `-define` (@janko-m)
53
+ * [minimagick] Add `#define` as a wrapper around `-define` (@janko)
50
54
 
51
55
  ## 1.1.0 (2018-04-05)
52
56
 
53
57
  * [minimagick] Disallow splitting multi-layer images into multiple single-layer
54
58
  images by default to avoid unexpected behaviour, but can be re-enabled with
55
- the `:allow_splitting` saver option (@janko-m)
59
+ the `:allow_splitting` saver option (@janko)
56
60
 
57
- * [core] Add `#apply` for applying a list of operations (@janko-m)
61
+ * [core] Add `#apply` for applying a list of operations (@janko)
58
62
 
59
63
  ## 1.0.0 (2018-04-04)
60
64
 
61
- * Depend on `mini_magick` and `ruby-vips` gems (@janko-m, @mokolabs)
65
+ * Depend on `mini_magick` and `ruby-vips` gems (@janko, @mokolabs)
62
66
 
63
- * [minimagick] Remove deprecated API in favor of the chainable API (@janko-m)
67
+ * [minimagick] Remove deprecated API in favor of the chainable API (@janko)
64
68
 
65
- * [core] Rename `Builder#default_options` to `Builder#options` (@janko-m)
69
+ * [core] Rename `Builder#default_options` to `Builder#options` (@janko)
66
70
 
67
- * [minimagick] Remove `:fail` loader option in favor of the existing `:regard_warnings` (@janko-m)
71
+ * [minimagick] Remove `:fail` loader option in favor of the existing `:regard_warnings` (@janko)
68
72
 
69
- * [vips, minimagick] Don't fail on warnings when loading the image (@janko-m)
73
+ * [vips, minimagick] Don't fail on warnings when loading the image (@janko)
70
74
 
71
- * [vips] Don't apply `Vips::Image#autorot` if `:autorotate` loader option was passed in (@janko-m)
75
+ * [vips] Don't apply `Vips::Image#autorot` if `:autorotate` loader option was passed in (@janko)
72
76
 
73
- * [minimagick] Allow using value `nil` to add ImageMagick options that don't have a value (@janko-m)
77
+ * [minimagick] Allow using value `nil` to add ImageMagick options that don't have a value (@janko)
74
78
 
75
- * [vips] Accept `:quality` saver option as an alias to `:Q` (@janko-m)
79
+ * [vips] Accept `:quality` saver option as an alias to `:Q` (@janko)
76
80
 
77
- * [minimagick] Automatically sharpen thumbnails after resizing (@janko-m, @mokolabs)
81
+ * [minimagick] Automatically sharpen thumbnails after resizing (@janko, @mokolabs)
78
82
 
79
- * [vips] Automatically sharpen thumbnails after resizing (@janko-m, @mokolabs)
83
+ * [vips] Automatically sharpen thumbnails after resizing (@janko, @mokolabs)
80
84
 
81
85
  ## 0.11.2 (2018-03-31)
82
86
 
83
- * [minimagick] Avoid `#resize_*` operations stripping data by switching back to `-resize` (@janko-m)
87
+ * [minimagick] Avoid `#resize_*` operations stripping data by switching back to `-resize` (@janko)
84
88
 
85
- * [core] Make sure an empty destination file doesn't remain on processing errors when `:destination` is used (@janko-m)
89
+ * [core] Make sure an empty destination file doesn't remain on processing errors when `:destination` is used (@janko)
86
90
 
87
- * [vips] Fix `:alpha` not correctly adding alpha for certain types of images (@janko-m)
91
+ * [vips] Fix `:alpha` not correctly adding alpha for certain types of images (@janko)
88
92
 
89
93
  ## 0.11.1 (2018-03-27)
90
94
 
91
- * [minimagick] Rename `#limit` to `#limits` to still allow adding `-limit` arguments directly (@janko-m)
95
+ * [minimagick] Rename `#limit` to `#limits` to still allow adding `-limit` arguments directly (@janko)
92
96
 
93
97
  ## 0.11.0 (2018-03-27)
94
98
 
95
- * [minimagick] Fix broken deprecated `#convert` (@janko-m)
99
+ * [minimagick] Fix broken deprecated `#convert` (@janko)
96
100
 
97
- * [minimagick] Add `#limit` for specifying resource limits using `-limit` (@janko-m)
101
+ * [minimagick] Add `#limit` for specifying resource limits using `-limit` (@janko)
98
102
 
99
- * [minimagick] Use `-thumbnail` instead of `-resize` in `#resize_*` methods (@janko-m)
103
+ * [minimagick] Use `-thumbnail` instead of `-resize` in `#resize_*` methods (@janko)
100
104
 
101
- * [minimagick] Add loader and saver options (@janko-m)
105
+ * [minimagick] Add loader and saver options (@janko)
102
106
 
103
107
  ## 0.10.3 (2018-03-24)
104
108
 
105
- * [minimagick] Fix bang methods in deprecated API calling nondestructive versions (@janko-m)
109
+ * [minimagick] Fix bang methods in deprecated API calling nondestructive versions (@janko)
106
110
 
107
111
  ## 0.10.2 (2018-03-22)
108
112
 
109
- * [minimagick] Add back default offset arguments to deprecated `#crop` (@janko-m)
113
+ * [minimagick] Add back default offset arguments to deprecated `#crop` (@janko)
110
114
 
111
115
  ## 0.10.1 (2018-03-22)
112
116
 
113
- * [minimagick] Don't print deprecation warning for old API twice when IO objects are used (@janko-m)
117
+ * [minimagick] Don't print deprecation warning for old API twice when IO objects are used (@janko)
114
118
 
115
119
  ## 0.10.0 (2018-03-21)
116
120
 
117
- * [minimagick] Rewrite MiniMagick module to use the chainable API (@janko-m)
121
+ * [minimagick] Rewrite MiniMagick module to use the chainable API (@janko)
118
122
 
119
- * [minimagick] Deprecate the old API (@janko-m)
123
+ * [minimagick] Deprecate the old API (@janko)
120
124
 
121
- * [minimagick] Raise an exception on processing warnings (@janko-m)
125
+ * [minimagick] Raise an exception on processing warnings (@janko)
122
126
 
123
- * [minimagick] Speed up `.valid_image?` by an order of magnitude (@janko-m)
127
+ * [minimagick] Speed up `.valid_image?` by an order of magnitude (@janko)
124
128
 
125
- * [minimagick] Don't accept arbitrary IO object anymore (@janko-m)
129
+ * [minimagick] Don't accept arbitrary IO object anymore (@janko)
126
130
 
127
- * [minimagick] Removed unnecessary `#crop` and `#resample` macros (@janko-m)
131
+ * [minimagick] Removed unnecessary `#crop` and `#resample` macros (@janko)
128
132
 
129
- * [vips] Ignore undefined loader/saver options (@janko-m)
133
+ * [vips] Ignore undefined loader/saver options (@janko)
130
134
 
131
- * [vips] Preserve transparent background in `#resize_to_pad` (@janko-m)
135
+ * [vips] Preserve transparent background in `#resize_to_pad` (@janko)
132
136
 
133
- * [vips] Remove the ability to specify colors using names (@janko-m)
137
+ * [vips] Remove the ability to specify colors using names (@janko)
134
138
 
135
- * [minimagick, vips] Autorotate images after loading them (@janko-m)
139
+ * [minimagick, vips] Autorotate images after loading them (@janko)
136
140
 
137
- * [core] Delete result `Tempfile` object in case of processing errors (@janko-m)
141
+ * [core] Delete result `Tempfile` object in case of processing errors (@janko)
138
142
 
139
- * [core] Allow returning `nil` in the `#custom` block (@janko-m)
143
+ * [core] Allow returning `nil` in the `#custom` block (@janko)
140
144
 
141
- * [core] Allow specifying a path string as source file (@janko-m)
145
+ * [core] Allow specifying a path string as source file (@janko)
142
146
 
143
- * [core] Allow saving to a specific location with the `:destination` call option (@janko-m)
147
+ * [core] Allow saving to a specific location with the `:destination` call option (@janko)
144
148
 
145
149
  ## 0.9.0 (2018-03-16)
146
150
 
147
- * Added libvips module (@GustavoCaso, @janko-m)
151
+ * Added libvips module (@GustavoCaso, @janko)
148
152
 
149
153
  * Drop official support for MRI 2.0 and 2.1
150
154
 
@@ -154,15 +158,15 @@
154
158
 
155
159
  ## 0.4.4 (2017-06-16)
156
160
 
157
- * Fix last changes being incompatible with older Ruby versions, again (@janko-m)
161
+ * Fix last changes being incompatible with older Ruby versions, again (@janko)
158
162
 
159
163
  ## 0.4.3 (2017-06-16)
160
164
 
161
- * Fix last changes being incompatible with older Ruby versions (@janko-m)
165
+ * Fix last changes being incompatible with older Ruby versions (@janko)
162
166
 
163
167
  ## 0.4.2 (2017-06-16)
164
168
 
165
- * Don't use path of input file as basename for output file (@janko-m)
169
+ * Don't use path of input file as basename for output file (@janko)
166
170
 
167
171
  ## 0.4.1 (2016-09-08)
168
172
 
data/README.md CHANGED
@@ -6,8 +6,8 @@ when handling image uploads.
6
6
  This gem can process images with either [ImageMagick]/[GraphicsMagick] or
7
7
  [libvips] libraries. ImageMagick is a good default choice, especially if you
8
8
  are migrating from another gem or library that uses ImageMagick. Libvips is a
9
- newer library that can process images [very rapidly][libvips performance] (up
10
- to 10x faster than ImageMagick).
9
+ newer library that can process images [very rapidly][libvips performance]
10
+ (often multiple times faster than ImageMagick).
11
11
 
12
12
 
13
13
  ## Goal
@@ -184,9 +184,9 @@ The `ImageProcessing::MiniMagick` functionality was extracted from
184
184
  [libvips]: http://libvips.github.io/libvips/
185
185
  [ImageMagick]: https://www.imagemagick.org
186
186
  [GraphicsMagick]: http://www.graphicsmagick.org
187
- [`ImageProcessing::Vips`]: /doc/vips.md#imageprocessingvips
188
- [`ImageProcessing::MiniMagick`]: /doc/minimagick.md#imageprocessingminimagick
187
+ [`ImageProcessing::Vips`]: doc/vips.md#readme
188
+ [`ImageProcessing::MiniMagick`]: doc/minimagick.md#readme
189
189
  [refile-mini_magick]: https://github.com/refile/refile-mini_magick
190
- [wiki]: https://github.com/janko-m/image_processing/wiki
190
+ [wiki]: https://github.com/janko/image_processing/wiki
191
191
  [HTTP.rb]: https://github.com/httprb/http
192
- [libvips performance]: https://github.com/jcupitt/libvips/wiki/Speed-and-memory-use
192
+ [libvips performance]: https://github.com/libvips/libvips/wiki/Speed-and-memory-use
@@ -1,4 +1,4 @@
1
- require File.expand_path('../lib/image_processing/version', __FILE__)
1
+ require File.expand_path("../lib/image_processing/version", __FILE__)
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "image_processing"
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
 
9
9
  spec.summary = "Set of higher-level helper methods for image processing."
10
10
  spec.description = "Set of higher-level helper methods for image processing."
11
- spec.homepage = "https://github.com/janko-m/image_processing"
11
+ spec.homepage = "https://github.com/janko/image_processing"
12
12
  spec.authors = ["Janko Marohnić"]
13
13
  spec.email = ["janko.marohnic@gmail.com"]
14
14
  spec.license = "MIT"
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.files = Dir["README.md", "LICENSE.txt", "CHANGELOG.md", "lib/**/*.rb", "*.gemspec"]
17
17
  spec.require_paths = ["lib"]
18
18
 
19
- spec.add_dependency "mini_magick", "~> 4.0"
19
+ spec.add_dependency "mini_magick", ">= 4.9.3", "< 5"
20
20
  spec.add_dependency "ruby-vips", ">= 2.0.13", "< 3"
21
21
 
22
22
  spec.add_development_dependency "rake"
@@ -25,7 +25,7 @@ module ImageProcessing
25
25
  # Initializes the image on disk into a MiniMagick::Tool object. Accepts
26
26
  # additional options related to loading the image (e.g. geometry).
27
27
  # Additionally auto-orients the image to be upright.
28
- def self.load_image(path_or_magick, page: nil, geometry: nil, auto_orient: true, **options)
28
+ def self.load_image(path_or_magick, operations: [], page: nil, geometry: nil, auto_orient: true, **options)
29
29
  if path_or_magick.is_a?(::MiniMagick::Tool)
30
30
  magick = path_or_magick
31
31
  else
@@ -195,7 +195,7 @@ module ImageProcessing
195
195
 
196
196
  if layers.any?
197
197
  layers.each { |path| File.delete(path) }
198
- raise Error, "Multi-layer image is being converted into a single-layer format. You should either process individual layers or set :allow_splitting to true. See https://github.com/janko-m/image_processing/wiki/Splitting-a-PDF-into-multiple-images for how to process each layer individually."
198
+ raise Error, "Multi-layer image is being converted into a single-layer format. You should either process individual layers or set :allow_splitting to true. See https://github.com/janko/image_processing/wiki/Splitting-a-PDF-into-multiple-images for how to process each layer individually."
199
199
  end
200
200
  end
201
201
 
@@ -4,36 +4,28 @@ module ImageProcessing
4
4
  class Pipeline
5
5
  DEFAULT_FORMAT = "jpg"
6
6
 
7
- attr_reader :source, :loader, :saver, :format, :operations, :processor, :destination
7
+ attr_reader :loader, :saver, :format, :operations, :processor, :destination
8
8
 
9
9
  # Initializes the pipeline with all the processing options.
10
10
  def initialize(options)
11
+ fail Error, "source file is not provided" unless options[:source]
12
+
11
13
  options.each do |name, value|
12
- value = normalize_source(value, options) if name == :source
13
14
  instance_variable_set(:"@#{name}", value)
14
15
  end
15
16
  end
16
17
 
17
- # Performs the defined series of operations, and saves the result in a new
18
- # tempfile or a specified path on disk, or if `save: false` was passed in
19
- # returns the unsaved accumulator object that can be used for further
20
- # processing.
18
+ # Determines the destination and calls the processor.
21
19
  def call(save: true)
22
- accumulator = processor.load_image(source, **loader)
23
-
24
- operations.each do |name, args, block|
25
- accumulator = processor.apply_operation(accumulator, name, *args, &block)
26
- end
27
-
28
20
  if save == false
29
- accumulator
21
+ call_processor
30
22
  elsif destination
31
23
  handle_destination do
32
- processor.save_image(accumulator, destination, **saver)
24
+ call_processor(destination: destination)
33
25
  end
34
26
  else
35
27
  create_tempfile do |tempfile|
36
- processor.save_image(accumulator, tempfile.path, **saver)
28
+ call_processor(destination: tempfile.path)
37
29
  end
38
30
  end
39
31
  end
@@ -54,6 +46,16 @@ module ImageProcessing
54
46
 
55
47
  private
56
48
 
49
+ def call_processor(**options)
50
+ processor.call(
51
+ source: source,
52
+ loader: loader,
53
+ operations: operations,
54
+ saver: saver,
55
+ **options
56
+ )
57
+ end
58
+
57
59
  # Creates a new tempfile for the destination file, yields it, and refreshes
58
60
  # the file descriptor to get the updated file.
59
61
  def create_tempfile
@@ -80,21 +82,15 @@ module ImageProcessing
80
82
  end
81
83
 
82
84
  # Converts the source image object into a path or the accumulator object.
83
- def normalize_source(source, options)
84
- fail Error, "source file is not provided" unless source
85
-
86
- accumulator_class = options[:processor]::ACCUMULATOR_CLASS
87
-
88
- if source.is_a?(accumulator_class)
89
- source
90
- elsif source.is_a?(String)
91
- source
92
- elsif source.respond_to?(:path)
93
- source.path
94
- elsif source.respond_to?(:to_path)
95
- source.to_path
85
+ def source
86
+ if @source.is_a?(String)
87
+ @source
88
+ elsif @source.respond_to?(:path)
89
+ @source.path
90
+ elsif @source.respond_to?(:to_path)
91
+ @source.to_path
96
92
  else
97
- fail Error, "source file needs to respond to #path, or be a String, a Pathname, or a #{accumulator_class} object"
93
+ @source
98
94
  end
99
95
  end
100
96
  end
@@ -1,8 +1,26 @@
1
1
  module ImageProcessing
2
2
  # Abstract class inherited by individual processors.
3
3
  class Processor
4
+ def self.call(source:, loader:, operations:, saver:, destination: nil)
5
+ unless source.is_a?(String) || source.is_a?(self::ACCUMULATOR_CLASS)
6
+ fail Error, "invalid source: #{source.inspect}"
7
+ end
8
+
9
+ accumulator = load_image(source, operations: operations, **loader)
10
+
11
+ operations.each do |operation|
12
+ accumulator = apply_operation(accumulator, operation)
13
+ end
14
+
15
+ if destination
16
+ save_image(accumulator, destination, **saver)
17
+ else
18
+ accumulator
19
+ end
20
+ end
21
+
4
22
  # Use for processor subclasses to specify the name and the class of their
5
- # accumulator object (e.g. MiniMagic::Tool or Vips::Image).
23
+ # accumulator object (e.g. MiniMagick::Tool or Vips::Image).
6
24
  def self.accumulator(name, klass)
7
25
  define_method(name) { @accumulator }
8
26
  protected(name)
@@ -13,8 +31,8 @@ module ImageProcessing
13
31
  # defined on the processor (macro), calls it. Otherwise calls the
14
32
  # operation directly on the accumulator object. This provides a common
15
33
  # umbrella above defined macros and direct operations.
16
- def self.apply_operation(accumulator, name, *args, &block)
17
- if (instance_methods - Object.instance_methods).include?(name)
34
+ def self.apply_operation(accumulator, (name, args, block))
35
+ if method_defined?(name)
18
36
  instance = new(accumulator)
19
37
  instance.public_send(name, *args, &block)
20
38
  else
@@ -1,3 +1,3 @@
1
1
  module ImageProcessing
2
- VERSION = "1.7.1"
2
+ VERSION = "1.8.0"
3
3
  end
@@ -27,14 +27,20 @@ module ImageProcessing
27
27
  # Loads the image on disk into a Vips::Image object. Accepts additional
28
28
  # loader-specific options (e.g. interlacing). Afterwards auto-rotates the
29
29
  # image to be upright.
30
- def self.load_image(path_or_image, autorot: true, **options)
30
+ def self.load_image(path_or_image, operations: [], autorot: true, **options)
31
31
  if path_or_image.is_a?(::Vips::Image)
32
32
  image = path_or_image
33
33
  else
34
- source_path = path_or_image
35
- options = Utils.select_valid_loader_options(source_path, options)
34
+ path = path_or_image
36
35
 
37
- image = ::Vips::Image.new_from_file(source_path, **options)
36
+ # utilize resize-on-load optimization when possible
37
+ return path if operations.any? &&
38
+ operations[0][0].to_s.start_with?("resize_") &&
39
+ options.empty?
40
+
41
+ options = Utils.select_valid_loader_options(path, options)
42
+
43
+ image = ::Vips::Image.new_from_file(path, **options)
38
44
  end
39
45
 
40
46
  image = image.autorot if autorot && !options.key?(:autorotate)
@@ -77,9 +83,7 @@ module ImageProcessing
77
83
  image.gravity(gravity, width, height, extend: extend, background: background)
78
84
  end
79
85
 
80
- # Rotates the image by an arbitrary angle. Additional options can be
81
- # specified, such as background colors to fill in the gaps when rotating
82
- # with an angle which is not a multiple of 90 degrees.
86
+ # Rotates the image by an arbitrary angle.
83
87
  def rotate(degrees, **options)
84
88
  image.similarity(angle: degrees, **options)
85
89
  end
@@ -112,7 +116,7 @@ module ImageProcessing
112
116
  image.composite(overlay, mode, **options)
113
117
  end
114
118
 
115
- # make Vips::Image#set, #set_type, #set_value, and #move chainable
119
+ # make metadata setter methods chainable
116
120
  def set(*args) image.tap { |img| img.set(*args) } end
117
121
  def set_type(*args) image.tap { |img| img.set_type(*args) } end
118
122
  def set_value(*args) image.tap { |img| img.set_value(*args) } end
@@ -123,8 +127,12 @@ module ImageProcessing
123
127
  # Resizes the image according to the specified parameters, and sharpens
124
128
  # the resulting thumbnail.
125
129
  def thumbnail(width, height, sharpen: SHARPEN_MASK, **options)
126
- image = self.image
127
- image = image.thumbnail_image(width, height: height, **options)
130
+ if self.image.is_a?(String) # path
131
+ # resize on load
132
+ image = ::Vips::Image.thumbnail(self.image, width, height: height, **options)
133
+ else
134
+ image = self.image.thumbnail_image(width, height: height, **options)
135
+ end
128
136
  image = image.conv(sharpen) if sharpen
129
137
  image
130
138
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: image_processing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-26 00:00:00.000000000 Z
11
+ date: 2019-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_magick
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.9.3
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '4.0'
22
+ version: '5'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 4.9.3
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '4.0'
32
+ version: '5'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: ruby-vips
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -133,7 +139,7 @@ files:
133
139
  - lib/image_processing/processor.rb
134
140
  - lib/image_processing/version.rb
135
141
  - lib/image_processing/vips.rb
136
- homepage: https://github.com/janko-m/image_processing
142
+ homepage: https://github.com/janko/image_processing
137
143
  licenses:
138
144
  - MIT
139
145
  metadata: {}
@@ -152,8 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
158
  - !ruby/object:Gem::Version
153
159
  version: '0'
154
160
  requirements: []
155
- rubyforge_project:
156
- rubygems_version: 2.7.6
161
+ rubygems_version: 3.0.1
157
162
  signing_key:
158
163
  specification_version: 4
159
164
  summary: Set of higher-level helper methods for image processing.