ruby-vips 2.0.16 → 2.0.17
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 +4 -4
- data/.rubocop_todo.yml +1 -1
- data/.travis.yml +1 -6
- data/CHANGELOG.md +11 -0
- data/README.md +38 -37
- data/TODO +1 -1
- data/VERSION +1 -1
- data/example/connection.rb +17 -0
- data/example/progress.rb +30 -0
- data/lib/vips.rb +64 -4
- data/lib/vips/connection.rb +46 -0
- data/lib/vips/gobject.rb +9 -1
- data/lib/vips/gvalue.rb +13 -4
- data/lib/vips/image.rb +213 -112
- data/lib/vips/methods.rb +330 -40
- data/lib/vips/object.rb +123 -5
- data/lib/vips/operation.rb +156 -80
- data/lib/vips/region.rb +2 -2
- data/lib/vips/source.rb +89 -0
- data/lib/vips/sourcecustom.rb +90 -0
- data/lib/vips/target.rb +87 -0
- data/lib/vips/targetcustom.rb +78 -0
- data/lib/vips/version.rb +1 -1
- data/ruby-vips.gemspec +3 -1
- metadata +14 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e63754294a1cbf0c65135dca3b377085616a6e386fb75d6442937fccb9c4c5a
|
4
|
+
data.tar.gz: d885bef5779402c0fbdc100635d8f26794d4d7394c97ac4eb1829343aaa5d636
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c52c6e54dc34dba9d01eb39dafc9e8d4132f3242d0a30ec89ea661c0b6d1be424ba6287398f13e697069e3a3d0f07e175f28f2f0f0b51caaed9cea8dc21aeee
|
7
|
+
data.tar.gz: 72e1116ca589860cbe30a3f6b89a7ca07a9d594b2be972a1cedad779a255a8d9418c5f9d472c90c1be63e76e518972d2ad48c73d31472aa8cf070ce668f29050
|
data/.rubocop_todo.yml
CHANGED
data/.travis.yml
CHANGED
@@ -45,6 +45,7 @@ rvm:
|
|
45
45
|
- 2.4
|
46
46
|
- 2.5
|
47
47
|
- 2.6
|
48
|
+
- 2.7
|
48
49
|
|
49
50
|
script: bundle exec rake spec
|
50
51
|
|
@@ -54,9 +55,3 @@ gemfile:
|
|
54
55
|
before_install:
|
55
56
|
- uname -a
|
56
57
|
- bash install-vips.sh
|
57
|
-
|
58
|
-
jobs:
|
59
|
-
include:
|
60
|
-
- stage: Lint
|
61
|
-
rvm: 2.6
|
62
|
-
script: bundle exec rake rubocop
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## Version 2.0.17 (2019-10-29)
|
6
|
+
|
7
|
+
* install msys2 libvips on Windows [larskanis]
|
8
|
+
* better `-` to `_` conversion [Nakilon]
|
9
|
+
* fix `GValue#set` for stricter metadata rules in 8.9 [jcupitt]
|
10
|
+
* fix a ref leak on operation build error [jcupitt]
|
11
|
+
* faster operation call [jcupitt]
|
12
|
+
* add support for VipsConnection [jcupitt]
|
13
|
+
* add `signal_connect` [jcupitt]
|
14
|
+
* add `Image#set_kill` for progress termination [jcupitt]
|
15
|
+
|
5
16
|
## Version 2.0.16 (2019-9-21)
|
6
17
|
|
7
18
|
* better library name generation [renchap]
|
data/README.md
CHANGED
@@ -3,35 +3,15 @@
|
|
3
3
|
[](https://badge.fury.io/rb/ruby-vips)
|
4
4
|
[](https://travis-ci.org/libvips/ruby-vips)
|
5
5
|
|
6
|
-
This gem
|
6
|
+
This gem is a Ruby binding for the [libvips image processing
|
7
7
|
library](https://libvips.github.io/libvips).
|
8
8
|
|
9
|
-
Programs that use `ruby-vips` don't
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
Because `ruby-vips` is parallel, it's quick, and because it doesn't need to
|
16
|
-
keep entire images in memory, it's light. For example, the benchmark at
|
17
|
-
[vips-benchmarks](https://github.com/jcupitt/vips-benchmarks) loads a
|
18
|
-
large image, crops, shrinks, sharpens and saves again, and repeats 10 times.
|
19
|
-
|
20
|
-
```text
|
21
|
-
real time in seconds, fastest of five runs
|
22
|
-
benchmark tiff jpeg
|
23
|
-
ruby-vips.rb 0.85 0.78
|
24
|
-
image-magick 2.03 2.44
|
25
|
-
rmagick.rb 3.87 3.89
|
26
|
-
|
27
|
-
peak memory use in kb
|
28
|
-
benchmark peak RES
|
29
|
-
ruby-vips.rb 43864
|
30
|
-
rmagick.rb 788768
|
31
|
-
```
|
32
|
-
|
33
|
-
See also [benchmarks at the official libvips
|
34
|
-
website](https://github.com/libvips/libvips/wiki/Speed-and-memory-use).
|
9
|
+
Programs that use `ruby-vips` don't manipulate images directly, instead
|
10
|
+
they create pipelines of image processing operations building on a source
|
11
|
+
image. When the end of the pipe is connected to a destination, the whole
|
12
|
+
pipeline executes at once, streaming the image in parallel from source to
|
13
|
+
destination a section at a time. Because `ruby-vips` is parallel, it's quick,
|
14
|
+
and because it doesn't need to keep entire images in memory, it's light.
|
35
15
|
|
36
16
|
## Requirements
|
37
17
|
|
@@ -60,9 +40,6 @@ gem 'ruby-vips'
|
|
60
40
|
On Windows, you'll need to set the `RUBY_DLL_PATH` environment variable to
|
61
41
|
point to the libvips bin directory.
|
62
42
|
|
63
|
-
Take a look in `examples/`. There is [full API
|
64
|
-
documentation](http://www.rubydoc.info/gems/ruby-vips).
|
65
|
-
|
66
43
|
# Example
|
67
44
|
|
68
45
|
```ruby
|
@@ -90,13 +67,37 @@ im = im.conv mask, precision: :integer
|
|
90
67
|
im.write_to_file output_filename
|
91
68
|
```
|
92
69
|
|
93
|
-
|
70
|
+
The `Vips` section in the API docs has a [tutorial introduction with
|
71
|
+
examples](https://www.rubydoc.info/gems/ruby-vips/Vips).
|
94
72
|
|
95
|
-
|
73
|
+
ruby-vips has [API
|
74
|
+
documentation](http://www.rubydoc.info/gems/ruby-vips). The [libvips
|
75
|
+
reference manual](https://libvips.github.io/libvips/API/current/) has a
|
76
|
+
complete explanation of every method.
|
96
77
|
|
97
|
-
The
|
98
|
-
|
78
|
+
The
|
79
|
+
[`example/`](https://github.com/libvips/ruby-vips/tree/master/example)
|
80
|
+
directory has some simple example programs.
|
81
|
+
|
82
|
+
# Benchmarks
|
83
|
+
|
84
|
+
The benchmark at [vips-benchmarks](https://github.com/jcupitt/vips-benchmarks)
|
85
|
+
loads a large image, crops, shrinks, sharpens and saves again, and repeats
|
86
|
+
10 times.
|
87
|
+
|
88
|
+
```text
|
89
|
+
real time in seconds, fastest of five runs
|
90
|
+
benchmark tiff jpeg
|
91
|
+
ruby-vips.rb 0.85 0.78
|
92
|
+
image-magick 2.03 2.44
|
93
|
+
rmagick.rb 3.87 3.89
|
94
|
+
|
95
|
+
peak memory use in kb
|
96
|
+
benchmark peak RES
|
97
|
+
ruby-vips.rb 43864
|
98
|
+
rmagick.rb 788768
|
99
|
+
```
|
100
|
+
|
101
|
+
See also [benchmarks at the official libvips
|
102
|
+
website](https://github.com/libvips/libvips/wiki/Speed-and-memory-use).
|
99
103
|
|
100
|
-
The `1.0-stable` branch is based on `gobject-introspection` rather than
|
101
|
-
`ffi`. It supports the same API as the current version, but is harder to
|
102
|
-
install, less portable, slower, and less stable.
|
data/TODO
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.
|
1
|
+
2.0.17
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'vips'
|
4
|
+
|
5
|
+
file = File.open ARGV[0], "rb"
|
6
|
+
source = Vips::SourceCustom.new
|
7
|
+
source.on_read { |length| file.read length }
|
8
|
+
# this method is optional
|
9
|
+
# source.on_seek { |offset, whence| file.seek(offset, whence) }
|
10
|
+
|
11
|
+
dest = File.open ARGV[1], "wb"
|
12
|
+
target = Vips::TargetCustom.new
|
13
|
+
target.on_write { |chunk| dest.write(chunk) }
|
14
|
+
target.on_finish { dest.close }
|
15
|
+
|
16
|
+
image = Vips::Image.new_from_source source, "", access: :sequential
|
17
|
+
image.write_to_target target, ".png"
|
data/example/progress.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'vips'
|
4
|
+
|
5
|
+
image = Vips::Image.black 1, 100000
|
6
|
+
image.set_progress true
|
7
|
+
|
8
|
+
def progress_to_s(name, progress)
|
9
|
+
puts "#{name}:"
|
10
|
+
puts " progress.run = #{progress[:run]}"
|
11
|
+
puts " progress.eta = #{progress[:eta]}"
|
12
|
+
puts " progress.tpels = #{progress[:tpels]}"
|
13
|
+
puts " progress.npels = #{progress[:npels]}"
|
14
|
+
puts " progress.percent = #{progress[:percent]}"
|
15
|
+
end
|
16
|
+
|
17
|
+
image.signal_connect :preeval do |progress|
|
18
|
+
progress_to_s("preeval", progress)
|
19
|
+
end
|
20
|
+
|
21
|
+
image.signal_connect :eval do |progress|
|
22
|
+
progress_to_s("eval", progress)
|
23
|
+
image.set_kill(true) if progress[:percent] > 50
|
24
|
+
end
|
25
|
+
|
26
|
+
image.signal_connect :posteval do |progress|
|
27
|
+
progress_to_s("posteval", progress)
|
28
|
+
end
|
29
|
+
|
30
|
+
image.avg
|
data/lib/vips.rb
CHANGED
@@ -166,7 +166,7 @@ require 'vips/gobject'
|
|
166
166
|
require 'vips/gvalue'
|
167
167
|
|
168
168
|
# This module provides a binding for the [libvips image processing
|
169
|
-
# library](https://
|
169
|
+
# library](https://libvips.github.io/libvips/).
|
170
170
|
#
|
171
171
|
# # Example
|
172
172
|
#
|
@@ -212,6 +212,9 @@ require 'vips/gvalue'
|
|
212
212
|
# memory buffers, create images that wrap C-style memory arrays, or make images
|
213
213
|
# from constants.
|
214
214
|
#
|
215
|
+
# Use {Source} and {Image.new_from_source} to load images from any data
|
216
|
+
# source, for example URIs.
|
217
|
+
#
|
215
218
|
# The next line:
|
216
219
|
#
|
217
220
|
# ```ruby
|
@@ -253,6 +256,9 @@ require 'vips/gvalue'
|
|
253
256
|
# suffix. You can also write formatted images to memory buffers, or dump
|
254
257
|
# image data to a raw memory array.
|
255
258
|
#
|
259
|
+
# Use {Target} and {Image#write_to_target} to write formatted images to
|
260
|
+
# any data sink, for example URIs.
|
261
|
+
#
|
256
262
|
# # How it works
|
257
263
|
#
|
258
264
|
# The binding uses [ruby-ffi](https://github.com/ffi/ffi) to open the libvips
|
@@ -404,12 +410,12 @@ require 'vips/gvalue'
|
|
404
410
|
# # Automatic YARD documentation
|
405
411
|
#
|
406
412
|
# The bulk of these API docs are generated automatically by
|
407
|
-
# {Vips::
|
413
|
+
# {Vips::Yard::generate}. It examines
|
408
414
|
# libvips and writes a summary of each operation and the arguments and options
|
409
415
|
# that that operation expects.
|
410
416
|
#
|
411
417
|
# Use the [C API
|
412
|
-
# docs](https://
|
418
|
+
# docs](https://libvips.github.io/libvips/API/current)
|
413
419
|
# for more detail.
|
414
420
|
#
|
415
421
|
# # Enums
|
@@ -434,6 +440,55 @@ require 'vips/gvalue'
|
|
434
440
|
# If you want to avoid the copies, you'll need to call drawing operations
|
435
441
|
# yourself.
|
436
442
|
#
|
443
|
+
# # Progress
|
444
|
+
#
|
445
|
+
# You can attach signal handlers to images to watch computation progress. For
|
446
|
+
# example:
|
447
|
+
#
|
448
|
+
# ```ruby
|
449
|
+
# image = Vips::Image.black 1, 100000
|
450
|
+
# image.set_progress true
|
451
|
+
#
|
452
|
+
# def progress_to_s(name, progress)
|
453
|
+
# puts "#{name}:"
|
454
|
+
# puts " run = #{progress[:run]}"
|
455
|
+
# puts " eta = #{progress[:eta]}"
|
456
|
+
# puts " tpels = #{progress[:tpels]}"
|
457
|
+
# puts " npels = #{progress[:npels]}"
|
458
|
+
# puts " percent = #{progress[:percent]}"
|
459
|
+
# end
|
460
|
+
#
|
461
|
+
# image.signal_connect :preeval do |progress|
|
462
|
+
# progress_to_s("preeval", progress)
|
463
|
+
# end
|
464
|
+
#
|
465
|
+
# image.signal_connect :eval do |progress|
|
466
|
+
# progress_to_s("eval", progress)
|
467
|
+
# image.set_kill(true) if progress[:percent] > 50
|
468
|
+
# end
|
469
|
+
#
|
470
|
+
# image.signal_connect :posteval do |progress|
|
471
|
+
# progress_to_s("posteval", progress)
|
472
|
+
# end
|
473
|
+
#
|
474
|
+
# image.avg
|
475
|
+
# ```
|
476
|
+
#
|
477
|
+
# The `:eval` signal will fire for every tile that is processed. You can stop
|
478
|
+
# progress with {Image#set_kill} and processing will end with an exception.
|
479
|
+
#
|
480
|
+
# User streams
|
481
|
+
#
|
482
|
+
# You can make your own input and output stream objects with {SourceCustom} and
|
483
|
+
# {TargetCustom}. For example:
|
484
|
+
#
|
485
|
+
# ```ruby
|
486
|
+
# file = File.open "some/file", "rb"
|
487
|
+
# source = Vips::SourceCustom.new
|
488
|
+
# source.on_read { |length| file.read length }
|
489
|
+
# image = Vips::Image.new_from_source source, "", access: "sequential"
|
490
|
+
# ```
|
491
|
+
#
|
437
492
|
# # Overloads
|
438
493
|
#
|
439
494
|
# The wrapper defines the usual set of arithmetic, boolean and relational
|
@@ -614,7 +669,7 @@ module Vips
|
|
614
669
|
LIBRARY_VERSION = Vips::version_string
|
615
670
|
|
616
671
|
# libvips has this arbitrary number as a sanity-check upper bound on image
|
617
|
-
# size. It's sometimes useful
|
672
|
+
# size. It's sometimes useful to know when calculating scale factors.
|
618
673
|
MAX_COORD = 10000000
|
619
674
|
end
|
620
675
|
|
@@ -624,3 +679,8 @@ require 'vips/image'
|
|
624
679
|
require 'vips/interpolate'
|
625
680
|
require 'vips/region'
|
626
681
|
require 'vips/version'
|
682
|
+
require 'vips/connection'
|
683
|
+
require 'vips/source'
|
684
|
+
require 'vips/sourcecustom'
|
685
|
+
require 'vips/target'
|
686
|
+
require 'vips/targetcustom'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# This module provides an interface to the top level bits of libvips
|
2
|
+
# via ruby-ffi.
|
3
|
+
#
|
4
|
+
# Author:: John Cupitt (mailto:jcupitt@gmail.com)
|
5
|
+
# License:: MIT
|
6
|
+
|
7
|
+
require 'ffi'
|
8
|
+
|
9
|
+
module Vips
|
10
|
+
if Vips::at_least_libvips?(8, 9)
|
11
|
+
attach_function :vips_connection_filename, [:pointer], :string
|
12
|
+
attach_function :vips_connection_nick, [:pointer], :string
|
13
|
+
end
|
14
|
+
|
15
|
+
# Abstract base class for connections.
|
16
|
+
class Connection < Vips::Object
|
17
|
+
# The layout of the VipsRegion struct.
|
18
|
+
module ConnectionLayout
|
19
|
+
def self.included(base)
|
20
|
+
base.class_eval do
|
21
|
+
layout :parent, Vips::Object::Struct
|
22
|
+
# rest opaque
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Struct < Vips::Object::Struct
|
28
|
+
include ConnectionLayout
|
29
|
+
end
|
30
|
+
|
31
|
+
class ManagedStruct < Vips::Object::ManagedStruct
|
32
|
+
include ConnectionLayout
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get any filename associated with a connection, or nil.
|
36
|
+
def filename
|
37
|
+
Vips::vips_connection_filename self
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get a nickname (short description) of a connection that could be shown to
|
41
|
+
# the user.
|
42
|
+
def nick
|
43
|
+
Vips::vips_connection_nick self
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/vips/gobject.rb
CHANGED
@@ -73,6 +73,9 @@ module GObject
|
|
73
73
|
def initialize ptr
|
74
74
|
# GLib::logger.debug("GObject::GObject.initialize") {"ptr = #{ptr}"}
|
75
75
|
@struct = ffi_managed_struct.new ptr
|
76
|
+
|
77
|
+
# sometimes we need to keep refs across C calls ... hide them here
|
78
|
+
@references = []
|
76
79
|
end
|
77
80
|
|
78
81
|
# access to the casting struct for this class
|
@@ -111,8 +114,13 @@ module GObject
|
|
111
114
|
layout :value, GParamSpec.ptr
|
112
115
|
end
|
113
116
|
|
114
|
-
attach_function :g_param_spec_get_blurb, [
|
117
|
+
attach_function :g_param_spec_get_blurb, [:pointer], :string
|
115
118
|
|
116
119
|
attach_function :g_object_ref, [:pointer], :void
|
117
120
|
attach_function :g_object_unref, [:pointer], :void
|
121
|
+
|
122
|
+
# we just use one gcallback type for every signal, hopefully this is OK
|
123
|
+
callback :gcallback, [:pointer], :void
|
124
|
+
attach_function :g_signal_connect_data,
|
125
|
+
[:pointer, :string, :gcallback, :pointer, :pointer, :int], :long
|
118
126
|
end
|
data/lib/vips/gvalue.rb
CHANGED
@@ -13,6 +13,8 @@ module GObject
|
|
13
13
|
# gvalue.init GObject::GDOUBLE_TYPE
|
14
14
|
# gvalue.set 3.1415
|
15
15
|
# value = gvalue.get
|
16
|
+
# # optional -- drop any ref the gvalue had
|
17
|
+
# gvalue.unset
|
16
18
|
# ```
|
17
19
|
#
|
18
20
|
# Lifetime is managed automatically. It doesn't know about all GType values,
|
@@ -25,12 +27,11 @@ module GObject
|
|
25
27
|
# convert an enum value (str/symb/int) into an int ready for libvips
|
26
28
|
def self.from_nick(gtype, value)
|
27
29
|
value = value.to_s if value.is_a? Symbol
|
28
|
-
# libvips expects "-" as a separator in enum names, but "_" is more
|
29
|
-
# convenient for ruby, eg. :b_w
|
30
|
-
value = value.tr("_", "-")
|
31
30
|
|
32
31
|
if value.is_a? String
|
33
|
-
|
32
|
+
# libvips expects "-" as a separator in enum names, but "_" is more
|
33
|
+
# convenient for ruby, eg. :b_w
|
34
|
+
value = Vips::vips_enum_from_nick "ruby-vips", gtype, value.tr("_", "-")
|
34
35
|
if value == -1
|
35
36
|
raise Vips::Error
|
36
37
|
end
|
@@ -244,6 +245,14 @@ module GObject
|
|
244
245
|
|
245
246
|
return result
|
246
247
|
end
|
248
|
+
|
249
|
+
# Clear the thing held by a GValue.
|
250
|
+
#
|
251
|
+
# This happens automatically when a GValue is GCed, but this method can be
|
252
|
+
# handy if you need to drop a reference explicitly for some reason.
|
253
|
+
def unset
|
254
|
+
::GObject::g_value_unset self
|
255
|
+
end
|
247
256
|
end
|
248
257
|
|
249
258
|
attach_function :g_value_init, [GValue.ptr, :GType], :void
|