dragonfly_libvips 0.1.5 → 1.0.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
  SHA1:
3
- metadata.gz: 9e30097336afa22dd5d34b9756c4d0d6f0b8c8cd
4
- data.tar.gz: 0deda2a95f1ac84b5824b410dbd366e9c4593fff
3
+ metadata.gz: ac436d551d9ccc732c27161a35c0f80962ca7746
4
+ data.tar.gz: 53eaccc65db78f1640ad11543e1eefb38b64139a
5
5
  SHA512:
6
- metadata.gz: ba270433cfe1379aed4440cefa2bac6f283a8050a249583065b4260227cfe2a8d7ca91ad8f67088e155e2376b64fc5a3f71553bbf6b7625f1c25b0e6518a8574
7
- data.tar.gz: 4f28259621db0d059df88687c8a86cdfb3797389fed0f0178d4c257b967273b43c36af440e8bd0f5afccccc68830ee32efb3194cca255698256705d822d1f028
6
+ metadata.gz: ee485134a812e6aba9808283c87bf55c07c31ca14d1d21abf92bc32e88055498c035b5c3e944685f4574fb586f78b3a5e4924a0c8b692f269916f4072a727c1f
7
+ data.tar.gz: bd2f3aae3d786b8840cc360f63533d7d597089871e4790759d80fe611812e64cb827b5d3ef2aa226ff10f73d3dfc065dc280c6d9b30ae6971e1672c30517ea71
data/.travis.yml CHANGED
@@ -6,11 +6,16 @@ sudo: required
6
6
  dist: trusty
7
7
  rvm:
8
8
  - 2.2.5
9
- env:
10
- - LIBVIPS_VERSION_MAJOR=8 LIBVIPS_VERSION_MINOR=3 LIBVIPS_VERSION_PATCH=3 LIBVIPS_VERSION=$LIBVIPS_VERSION_MAJOR.$LIBVIPS_VERSION_MINOR.$LIBVIPS_VERSION_PATCH
11
9
  before_install:
12
10
  - gem install bundler -v 1.12.5
13
- - curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | sudo bash -
11
+ - sudo apt-get update
12
+ - sudo apt-get install -y gobject-introspection libgirepository1.0-dev gtk-doc-tools libglib2.0-dev libpoppler-glib-dev
13
+ - export GI_TYPELIB_PATH="$VIPS_LIBDIR/girepository-1.0"
14
+ - curl -O https://poppler.freedesktop.org/poppler-0.51.0.tar.xz
15
+ - tar xf poppler-0.51.0.tar.xz && cd poppler-0.51.0 && ./configure --prefix=/usr --sysconfdir=/etc --disable-static --enable-build-type=release --enable-cmyk --enable-xpdf-headers --with-testdatadir=$PWD/testfiles && sudo make && sudo make install
16
+ - curl -O http://www.vips.ecs.soton.ac.uk/supported/8.4/vips-8.4.5.tar.gz
17
+ - tar zvxf vips-8.4.5.tar.gz && cd vips-8.4.5 && ./configure $1 --enable-introspection && sudo make && sudo make install
18
+ - sudo ldconfig
14
19
 
15
20
  notifications:
16
21
  email:
data/CHANGELOG.md CHANGED
@@ -0,0 +1,6 @@
1
+ # CHANGELOG
2
+
3
+ ## 1.0.0
4
+
5
+ * rewritten to use `ruby-vips` instead of CLI vips utils, which should result in better performance
6
+ * processors `convert`, `vips` and `vipsthumbnail` have been removed
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Dragonfly libvips
2
2
 
3
- [![Build Status](https://travis-ci.org/tomasc/dragonfly_libvips.svg)](https://travis-ci.org/tomasc/dragonfly_libvips) [![Gem Version](https://badge.fury.io/rb/dragonfly_libvips.svg)](http://badge.fury.io/rb/dragonfly_libvips) [![Coverage Status](https://img.shields.io/coveralls/tomasc/dragonfly_libvips.svg)](https://coveralls.io/r/tomasc/dragonfly_pdf)
3
+ [![Build Status](https://travis-ci.org/tomasc/dragonfly_libvips.svg)](https://travis-ci.org/tomasc/dragonfly_libvips) [![Gem Version](https://badge.fury.io/rb/dragonfly_libvips.svg)](http://badge.fury.io/rb/dragonfly_libvips) [![Coverage Status](https://img.shields.io/coveralls/tomasc/dragonfly_libvips.svg)](https://coveralls.io/r/tomasc/dragonfly_libvips)
4
4
 
5
5
  Dragonfly analysers and processors for [libvips](https://github.com/jcupitt/libvips) image processing library
6
6
 
@@ -73,7 +73,7 @@ image.encode('jpg')
73
73
  optionally pass output arguments (specific to format)
74
74
 
75
75
  ```ruby
76
- image.encode('jpg', 'Q=50')
76
+ image.encode('jpg')
77
77
  ```
78
78
 
79
79
  #### Rotate
@@ -84,41 +84,22 @@ Rotate a number of degrees with
84
84
  image.rotate(90)
85
85
  ```
86
86
 
87
- #### Vips
87
+ #### Options
88
88
 
89
- Perform an arbitrary `vips` command
89
+ All processors support `input_options` and `output_options` for passing additional options to vips. For example:
90
90
 
91
91
  ```ruby
92
- image.vips('resize', '0.5', { 'input_args' => 'page=2', 'output_args' => 'Q=50', 'format' => 'jpg' })
93
- ```
94
-
95
- corresponds to the command-line
96
-
97
- ```
98
- vips resize <original_path>[page=2] <new_path>[Q=50] 0.5
92
+ image.encode('jpg', output_options: { Q: 50 })
93
+ pdf.encode('jpg', input_options: { page: 0, dpi: 600 })
99
94
  ```
100
95
 
101
- #### Vipsthumbnail
102
-
103
- Perform an arbitrary `vipsthumbnail` command
96
+ Defaults:
104
97
 
105
98
  ```ruby
106
- image.vipsthumbnail('--size=100x100', { 'input_args' => 'page=2', 'output_args' => 'Q=50', 'format' => 'jpg' })
99
+ input_options: { access: :sequential }
100
+ output_options: { profile: … } # embeds 'sRGB_v4_ICC_preference.icc' profile included with this gem
107
101
  ```
108
102
 
109
- corresponds to the command-line
110
-
111
- ```
112
- vipsthumbnail <original_path>[page=2] --size=100x100 -o <new-path>[Q=50] --eprofile=./vendor/sRGB_v4_ICC_preference.icc
113
- ```
114
-
115
- Please note that unless specified a default sRGB profile is added (required for conversion from CMYK, for example). It can be overridden by specifying alternative on in the processors args:
116
-
117
- ```ruby
118
- image.vipsthumbnail('--size=100x100 --eprofile=./my_custom_profile.icc')
119
- ```
120
-
121
-
122
103
  ### Analysers
123
104
 
124
105
  The following methods are provided
@@ -126,6 +107,8 @@ The following methods are provided
126
107
  ```ruby
127
108
  image.width # => 280
128
109
  image.height # => 355
110
+ image.xres # => 72.0
111
+ image.yres # => 72.0
129
112
  image.aspect_ratio # => 0.788732394366197
130
113
  image.portrait? # => true
131
114
  image.landscape? # => false
@@ -133,21 +116,6 @@ image.format # => 'png'
133
116
  image.image? # => true
134
117
  ```
135
118
 
136
- ### Configuration
137
-
138
- ```ruby
139
- Dragonfly.app.configure do
140
- plugin :libvips,
141
- vips_command: "/opt/local/bin/vips" # defaults to "vips"
142
- vipsheader_command: "/opt/local/bin/vipsheader" # defaults to "vipsheader"
143
- vipsthumbnail_command: "/opt/local/bin/vipsthumbnail" # defaults to "vipsthumbnail"
144
- end
145
- ```
146
-
147
- ## Acknowledgements
148
-
149
- This plugin, its structure, sample files, tests as well as this README are based on the original Dragonfly's [ImageMagick plugin](http://markevans.github.io/dragonfly/imagemagick) by Mark Evans.
150
-
151
119
  ## Development
152
120
 
153
121
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_dependency 'dragonfly', '~> 1.0'
22
+ spec.add_dependency 'ruby-vips', '~> 1.0'
23
+ spec.add_dependency 'activesupport', '>= 4.0'
22
24
 
23
25
  spec.add_development_dependency 'bundler', '~> 1.12'
24
26
  spec.add_development_dependency 'guard'
@@ -1,20 +1,17 @@
1
+ require 'vips'
2
+
1
3
  module DragonflyLibvips
2
4
  module Analysers
3
5
  class ImageProperties
4
6
  def call(content)
5
- vipsheader_command = content.env[:vipsheader_command] || 'vipsheader'
6
- details = content.shell_eval do |path|
7
- "#{vipsheader_command} #{path}"
8
- end
9
-
10
- _filename, dimensions, _bands, _interpretation, vips_loader = details.split(/\s*[:,]\s*/)
11
- width, height = dimensions.split(/\s+/).first.split('x')
12
- format = vips_loader.gsub(/\s*load\s*/, '').downcase
7
+ img = ::Vips::Image.new_from_file(content.path, access: :sequential)
13
8
 
14
9
  {
15
- 'format' => format.downcase,
16
- 'width' => width.to_i,
17
- 'height' => height.to_i
10
+ 'format' => content.ext,
11
+ 'width' => img.width,
12
+ 'height' => img.height,
13
+ 'xres' => img.xres,
14
+ 'yres' => img.yres
18
15
  }
19
16
  end
20
17
  end
@@ -5,8 +5,8 @@ module DragonflyLibvips
5
5
  end
6
6
 
7
7
  def call
8
- return OpenStruct.new(width: orig_w, height: orig_h) if do_not_resize_if_image_smaller_than_requested? || do_not_resize_if_image_larger_than_requested?
9
- OpenStruct.new(width: width, height: height)
8
+ return OpenStruct.new(width: orig_w, height: orig_h, scale: 1) if do_not_resize_if_image_smaller_than_requested? || do_not_resize_if_image_larger_than_requested?
9
+ OpenStruct.new(width: width, height: height, scale: scale)
10
10
  end
11
11
 
12
12
  private
@@ -27,6 +27,10 @@ module DragonflyLibvips
27
27
  end
28
28
  end
29
29
 
30
+ def scale
31
+ width.to_f / orig_w.to_f
32
+ end
33
+
30
34
  def dimensions
31
35
  w, h = geometry.scan(/\A(\d*)x(\d*)/).flatten.map(&:to_f)
32
36
  OpenStruct.new(width: w, height: h)
@@ -1,18 +1,11 @@
1
- require 'dragonfly/shell'
2
1
  require 'dragonfly_libvips/analysers/image_properties'
3
2
  require 'dragonfly_libvips/processors/encode'
3
+ require 'dragonfly_libvips/processors/rotate'
4
4
  require 'dragonfly_libvips/processors/thumb'
5
- require 'dragonfly_libvips/processors/vips'
6
- require 'dragonfly_libvips/processors/vipsthumbnail'
7
5
 
8
6
  module DragonflyLibvips
9
7
  class Plugin
10
- def call(app, opts = {})
11
- # ENV
12
- app.env[:vips_command] = opts[:vips_command] || 'vips'
13
- app.env[:vipsheader_command] = opts[:vipsheader_command] || 'vipsheader'
14
- app.env[:vipsthumbnail_command] = opts[:vipsthumbnail_command] || 'vipsthumbnail'
15
-
8
+ def call(app, _opts = {})
16
9
  # Analysers
17
10
  app.add_analyser :image_properties, DragonflyLibvips::Analysers::ImageProperties.new
18
11
 
@@ -24,6 +17,14 @@ module DragonflyLibvips
24
17
  content.analyse(:image_properties)['height']
25
18
  end
26
19
 
20
+ app.add_analyser :xres do |content|
21
+ content.analyse(:image_properties)['xres']
22
+ end
23
+
24
+ app.add_analyser :yres do |content|
25
+ content.analyse(:image_properties)['yres']
26
+ end
27
+
27
28
  app.add_analyser :format do |content|
28
29
  content.analyse(:image_properties)['format']
29
30
  end
@@ -45,7 +46,7 @@ module DragonflyLibvips
45
46
  app.add_analyser :image do |content|
46
47
  begin
47
48
  content.analyse(:image_properties).key?('format')
48
- rescue Dragonfly::Shell::CommandFailed
49
+ rescue ::Vips::Error
49
50
  false
50
51
  end
51
52
  end
@@ -58,19 +59,7 @@ module DragonflyLibvips
58
59
  # Processors
59
60
  app.add_processor :encode, Processors::Encode.new
60
61
  app.add_processor :thumb, Processors::Thumb.new
61
- app.add_processor :vips, Processors::Vips.new
62
- app.add_processor :vipsthumbnail, Processors::Vipsthumbnail.new
63
- app.add_processor :rotate do |content, amount|
64
- content.process!(:vips, 'rot', "d#{amount}")
65
- end
66
-
67
- # Extra methods
68
- app.define :vipsheader do |*args|
69
- cli_args = args.first # because ruby 1.8.7 can't deal with default args in blocks
70
- shell_eval do |path|
71
- "#{app.env[:vipsheader_command]} #{cli_args} #{path}"
72
- end
73
- end
62
+ app.add_processor :rotate, Processors::Rotate.new
74
63
  end
75
64
  end
76
65
  end
@@ -1,13 +1,26 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'vips'
3
+
1
4
  module DragonflyLibvips
2
5
  module Processors
3
6
  class Encode
4
- def call(content, format, output_args = '')
5
- opts = { 'format' => format, 'output_args' => output_args }
6
- content.process!(:vips, 'copy', '', opts)
7
+ def call(content, format, options = {})
8
+ options = options.deep_stringify_keys
9
+
10
+ input_options = options.fetch('input_options', {})
11
+ output_options = options.fetch('output_options', {})
12
+
13
+ input_options['access'] ||= 'sequential'
14
+ output_options['profile'] ||= DragonflyLibvips::EPROFILE_PATH
15
+
16
+ img = ::Vips::Image.new_from_file(content.path, input_options)
17
+
18
+ content.update(img.write_to_buffer(".#{format}", output_options), 'format' => format)
19
+ content.ext = format
7
20
  end
8
21
 
9
- def update_url(attrs, format, _args = '')
10
- attrs.ext = format.to_s
22
+ def update_url(url_attributes, format, options = {})
23
+ url_attributes.ext = format.to_s
11
24
  end
12
25
  end
13
26
  end
@@ -0,0 +1,35 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'vips'
3
+
4
+ module DragonflyLibvips
5
+ module Processors
6
+ class Rotate
7
+ def call(content, rotate, options = {})
8
+ options = options.deep_stringify_keys
9
+
10
+ format = options.fetch('format', content.ext)
11
+
12
+ input_options = options.fetch('input_options', {})
13
+ output_options = options.fetch('output_options', {})
14
+
15
+ input_options['access'] ||= 'sequential'
16
+ output_options['profile'] ||= DragonflyLibvips::EPROFILE_PATH
17
+
18
+ img = ::Vips::Image.new_from_file(content.path, input_options)
19
+
20
+ img = img.rot("d#{rotate}")
21
+
22
+ content.update(img.write_to_buffer(".#{format}", output_options), 'format' => format)
23
+ content.ext = format
24
+ end
25
+
26
+ def update_url(url_attributes, _, options = {})
27
+ options = options.deep_stringify_keys
28
+
29
+ if format = options.fetch('format', nil)
30
+ url_attributes.ext = format
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,34 +1,47 @@
1
+ require 'active_support/core_ext/hash'
1
2
  require 'dragonfly_libvips/dimensions'
3
+ require 'vips'
2
4
 
3
5
  module DragonflyLibvips
4
6
  module Processors
5
7
  class Thumb
6
8
  OPERATORS = '><'.freeze
7
9
  RESIZE_GEOMETRY = /\A\d*x\d*[#{OPERATORS}]?\z/ # e.g. '300x200>'
10
+ RESIZE_KEYS = %w(kernel).freeze
8
11
 
9
- def call(content, geometry, opts = {})
10
- image_properties = content.analyse(:image_properties)
11
- args = [args_for_geometry(geometry, image_properties), opts['args']].compact.join(' ')
12
- content.process!(:vipsthumbnail, args, opts)
13
- end
12
+ def call(content, geometry, options = {})
13
+ options = options.deep_stringify_keys
14
14
 
15
- def update_url(url_attributes, _geometry, opts = {})
16
- format = opts['format']
17
- url_attributes.ext = format if format
18
- end
15
+ format = options.fetch('format', content.ext)
16
+
17
+ input_options = options.fetch('input_options', {})
18
+ resize_options = options.fetch('resize_options', {})
19
+ output_options = options.fetch('output_options', {})
19
20
 
20
- private
21
+ input_options['access'] ||= 'sequential'
22
+ output_options['profile'] ||= DragonflyLibvips::EPROFILE_PATH
21
23
 
22
- def args_for_geometry(geometry, image_properties)
23
- case geometry
24
- when RESIZE_GEOMETRY then resize_args(geometry, image_properties)
25
- else raise ArgumentError, "Didn't recognise the geometry string #{geometry}"
24
+ img = ::Vips::Image.new_from_file(content.path, input_options)
25
+
26
+ dimensions = case geometry
27
+ when RESIZE_GEOMETRY then DragonflyLibvips::Dimensions.call(geometry, img.width, img.height)
28
+ else raise ArgumentError, "Didn't recognise the geometry string #{geometry}"
26
29
  end
30
+
31
+ if dimensions.scale != 1
32
+ img = img.resize(dimensions.scale, resize_options)
33
+ end
34
+
35
+ content.update(img.write_to_buffer(".#{format}", output_options), 'format' => format)
36
+ content.ext = format
27
37
  end
28
38
 
29
- def resize_args(geometry, image_properties)
30
- res = DragonflyLibvips::Dimensions.call(geometry, image_properties['width'], image_properties['height'])
31
- "-s #{res.width.round}x#{res.height.round}"
39
+ def update_url(url_attributes, _, options = {})
40
+ options = options.deep_stringify_keys
41
+
42
+ if format = options.fetch('format', nil)
43
+ url_attributes.ext = format
44
+ end
32
45
  end
33
46
  end
34
47
  end
@@ -1,3 +1,3 @@
1
1
  module DragonflyLibvips
2
- VERSION = '0.1.5'.freeze
2
+ VERSION = '1.0.2'.freeze
3
3
  end
@@ -2,6 +2,7 @@ require 'dragonfly'
2
2
  require 'dragonfly_libvips/dimensions'
3
3
  require 'dragonfly_libvips/plugin'
4
4
  require 'dragonfly_libvips/version'
5
+ require 'vips'
5
6
 
6
7
  module DragonflyLibvips
7
8
  EPROFILE_PATH = File.expand_path('../vendor/sRGB_v4_ICC_preference.icc', __dir__)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dragonfly_libvips
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Celizna
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-22 00:00:00.000000000 Z
11
+ date: 2017-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dragonfly
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby-vips
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -117,9 +145,8 @@ files:
117
145
  - lib/dragonfly_libvips/dimensions.rb
118
146
  - lib/dragonfly_libvips/plugin.rb
119
147
  - lib/dragonfly_libvips/processors/encode.rb
148
+ - lib/dragonfly_libvips/processors/rotate.rb
120
149
  - lib/dragonfly_libvips/processors/thumb.rb
121
- - lib/dragonfly_libvips/processors/vips.rb
122
- - lib/dragonfly_libvips/processors/vipsthumbnail.rb
123
150
  - lib/dragonfly_libvips/version.rb
124
151
  - samples/beach.png
125
152
  - samples/landscape_beach.png
@@ -1,32 +0,0 @@
1
- module DragonflyLibvips
2
- module Processors
3
- class Vips
4
- def call(content, commands, args = '', opts = {})
5
- vips_command = content.env[:vips_command] || 'vips'
6
- format = opts['format']
7
-
8
- if input_args = opts['input_args']
9
- input_args = "[#{input_args}]"
10
- end
11
-
12
- if output_args = opts['output_args']
13
- output_args = "[#{output_args}]"
14
- end
15
-
16
- content.shell_update ext: format do |old_path, new_path|
17
- "#{vips_command} #{commands} #{old_path}#{input_args} #{new_path}#{output_args} #{args}"
18
- end
19
-
20
- if format
21
- content.meta['format'] = format.to_s
22
- content.ext = format
23
- end
24
- end
25
-
26
- def update_url(attrs, _commands, _args = '', opts = {})
27
- format = opts['format']
28
- attrs.ext = format if format
29
- end
30
- end
31
- end
32
- end
@@ -1,36 +0,0 @@
1
- require 'dragonfly_libvips'
2
-
3
- module DragonflyLibvips
4
- module Processors
5
- class Vipsthumbnail
6
- def call(content, args = '', opts = {})
7
- vipsthumbnail_command = content.env[:vipsthumbnail_command] || 'vipsthumbnail'
8
- format = opts['format']
9
-
10
- if input_args = opts['input_args']
11
- input_args = "[#{input_args}]"
12
- end
13
-
14
- if output_args = opts['output_args']
15
- output_args = "[#{output_args}]"
16
- end
17
-
18
- args = [args, "--eprofile=#{EPROFILE_PATH}"].compact.join(' ') unless args.include?('eprofile')
19
-
20
- content.shell_update ext: format do |old_path, new_path|
21
- "#{vipsthumbnail_command} #{old_path}#{input_args} -o #{new_path}#{output_args} #{args}"
22
- end
23
-
24
- if format
25
- content.meta['format'] = format.to_s
26
- content.ext = format
27
- end
28
- end
29
-
30
- def update_url(attrs, _args = '', opts = {})
31
- format = opts['format']
32
- attrs.ext = format if format
33
- end
34
- end
35
- end
36
- end