vips 8.8.4 → 8.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +42 -0
- data/.github/workflows/development.yml +54 -0
- data/.standard.yml +17 -0
- data/.travis.yml +1 -0
- data/.yardopts +0 -1
- data/CHANGELOG.md +50 -0
- data/Gemfile +8 -1
- data/README.md +31 -15
- data/Rakefile +23 -18
- data/TODO +43 -0
- data/example/annotate.rb +6 -6
- data/example/connection.rb +26 -0
- data/example/daltonize8.rb +6 -6
- data/example/draw_lines.rb +30 -0
- data/example/example1.rb +4 -4
- data/example/example2.rb +6 -6
- data/example/example3.rb +5 -5
- data/example/example4.rb +2 -2
- data/example/example5.rb +4 -4
- data/example/inheritance_with_refcount.rb +46 -39
- data/example/progress.rb +30 -0
- data/example/thumb.rb +6 -6
- data/example/trim8.rb +1 -1
- data/example/watermark.rb +2 -2
- data/example/wobble.rb +1 -1
- data/lib/vips/blend_mode.rb +29 -25
- data/lib/vips/connection.rb +46 -0
- data/lib/vips/gobject.rb +27 -12
- data/lib/vips/gvalue.rb +62 -50
- data/lib/vips/image.rb +548 -287
- data/lib/vips/interpolate.rb +3 -2
- data/lib/vips/methods.rb +2877 -2319
- data/lib/vips/mutableimage.rb +173 -0
- data/lib/vips/object.rb +159 -54
- data/lib/vips/operation.rb +286 -117
- data/lib/vips/region.rb +73 -0
- data/lib/vips/source.rb +88 -0
- data/lib/vips/sourcecustom.rb +89 -0
- data/lib/vips/target.rb +86 -0
- data/lib/vips/targetcustom.rb +77 -0
- data/lib/vips/version.rb +1 -1
- data/lib/vips.rb +199 -80
- data/vips.gemspec +3 -3
- metadata +36 -22
data/lib/vips/source.rb
ADDED
@@ -0,0 +1,88 @@
|
|
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_source_new_from_descriptor, [:int], :pointer
|
12
|
+
attach_function :vips_source_new_from_file, [:pointer], :pointer
|
13
|
+
attach_function :vips_source_new_from_memory, [:pointer, :size_t], :pointer
|
14
|
+
end
|
15
|
+
|
16
|
+
# A source. For example:
|
17
|
+
#
|
18
|
+
# ```ruby
|
19
|
+
# source = Vips::Source.new_from_file("k2.jpg")
|
20
|
+
# image = Vips::Image.new_from_source(source)
|
21
|
+
# ```
|
22
|
+
class Source < Vips::Connection
|
23
|
+
module SourceLayout
|
24
|
+
def self.included(base)
|
25
|
+
base.class_eval do
|
26
|
+
layout :parent, Vips::Connection::Struct
|
27
|
+
# rest opaque
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Struct < Vips::Connection::Struct
|
33
|
+
include SourceLayout
|
34
|
+
end
|
35
|
+
|
36
|
+
class ManagedStruct < Vips::Connection::ManagedStruct
|
37
|
+
include SourceLayout
|
38
|
+
end
|
39
|
+
|
40
|
+
# Create a new source from a file descriptor. File descriptors are
|
41
|
+
# small integers, for example 0 is stdin.
|
42
|
+
#
|
43
|
+
# Pass sources to {Image.new_from_source} to load images from
|
44
|
+
# them.
|
45
|
+
#
|
46
|
+
# @param descriptor [Integer] the file descriptor
|
47
|
+
# @return [Source] the new Vips::Source
|
48
|
+
def self.new_from_descriptor(descriptor)
|
49
|
+
ptr = Vips.vips_source_new_from_descriptor descriptor
|
50
|
+
raise Vips::Error if ptr.null?
|
51
|
+
|
52
|
+
Vips::Source.new ptr
|
53
|
+
end
|
54
|
+
|
55
|
+
# Create a new source from a file name.
|
56
|
+
#
|
57
|
+
# Pass sources to {Image.new_from_source} to load images from
|
58
|
+
# them.
|
59
|
+
#
|
60
|
+
# @param filename [String] the name of the file
|
61
|
+
# @return [Source] the new Vips::Source
|
62
|
+
def self.new_from_file(filename)
|
63
|
+
raise Vips::Error, "filename is nil" if filename.nil?
|
64
|
+
ptr = Vips.vips_source_new_from_file filename
|
65
|
+
raise Vips::Error if ptr.null?
|
66
|
+
|
67
|
+
Vips::Source.new ptr
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create a new source from an area of memory. Memory areas can be
|
71
|
+
# strings, arrays and so forth -- anything that supports bytesize.
|
72
|
+
#
|
73
|
+
# Pass sources to {Image.new_from_source} to load images from
|
74
|
+
# them.
|
75
|
+
#
|
76
|
+
# @param data [String] memory area
|
77
|
+
# @return [Source] the new Vips::Source
|
78
|
+
def self.new_from_memory(data)
|
79
|
+
ptr = Vips.vips_source_new_from_memory data, data.bytesize
|
80
|
+
raise Vips::Error if ptr.null?
|
81
|
+
|
82
|
+
# FIXME do we need to keep a ref to the underlying memory area? what
|
83
|
+
# about Image.new_from_buffer? Does that need a secret ref too?
|
84
|
+
|
85
|
+
Vips::Source.new ptr
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,89 @@
|
|
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_source_custom_new, [], :pointer
|
12
|
+
end
|
13
|
+
|
14
|
+
# A source you can attach action signal handlers to to implement
|
15
|
+
# custom input types.
|
16
|
+
#
|
17
|
+
# For example:
|
18
|
+
#
|
19
|
+
# ```ruby
|
20
|
+
# file = File.open "some/file/name", "rb"
|
21
|
+
# source = Vips::SourceCustom.new
|
22
|
+
# source.on_read { |length| file.read length }
|
23
|
+
# image = Vips::Image.new_from_source source
|
24
|
+
# ```
|
25
|
+
#
|
26
|
+
# (just an example -- of course in practice you'd use {Source#new_from_file}
|
27
|
+
# to read from a named file)
|
28
|
+
class SourceCustom < Vips::Source
|
29
|
+
module SourceCustomLayout
|
30
|
+
def self.included(base)
|
31
|
+
base.class_eval do
|
32
|
+
layout :parent, Vips::Source::Struct
|
33
|
+
# rest opaque
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Struct < Vips::Source::Struct
|
39
|
+
include SourceCustomLayout
|
40
|
+
end
|
41
|
+
|
42
|
+
class ManagedStruct < Vips::Source::ManagedStruct
|
43
|
+
include SourceCustomLayout
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
pointer = Vips.vips_source_custom_new
|
48
|
+
raise Vips::Error if pointer.null?
|
49
|
+
|
50
|
+
super pointer
|
51
|
+
end
|
52
|
+
|
53
|
+
# The block is executed to read data from the source. The interface is
|
54
|
+
# exactly as IO::read, ie. it takes a maximum number of bytes to read and
|
55
|
+
# returns a string of bytes from the source, or nil if the source is already
|
56
|
+
# at end of file.
|
57
|
+
#
|
58
|
+
# @yieldparam length [Integer] Read and return up to this many bytes
|
59
|
+
# @yieldreturn [String] Up to length bytes of data, or nil for EOF
|
60
|
+
def on_read &block
|
61
|
+
signal_connect "read" do |buf, len|
|
62
|
+
chunk = block.call len
|
63
|
+
return 0 if chunk.nil?
|
64
|
+
bytes_read = chunk.bytesize
|
65
|
+
buf.put_bytes(0, chunk, 0, bytes_read)
|
66
|
+
chunk.clear
|
67
|
+
|
68
|
+
bytes_read
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# The block is executed to seek the source. The interface is exactly as
|
73
|
+
# IO::seek, ie. it should take an offset and whence, and return the
|
74
|
+
# new read position.
|
75
|
+
#
|
76
|
+
# This handler is optional -- if you do not attach a seek handler,
|
77
|
+
# {Source} will treat your source like an unseekable pipe object and
|
78
|
+
# do extra caching.
|
79
|
+
#
|
80
|
+
# @yieldparam offset [Integer] Seek offset
|
81
|
+
# @yieldparam whence [Integer] Seek whence
|
82
|
+
# @yieldreturn [Integer] the new read position, or -1 on error
|
83
|
+
def on_seek &block
|
84
|
+
signal_connect "seek" do |offset, whence|
|
85
|
+
block.call offset, whence
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/vips/target.rb
ADDED
@@ -0,0 +1,86 @@
|
|
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_target_new_to_descriptor, [:int], :pointer
|
12
|
+
attach_function :vips_target_new_to_file, [:string], :pointer
|
13
|
+
attach_function :vips_target_new_to_memory, [], :pointer
|
14
|
+
end
|
15
|
+
|
16
|
+
# A target. For example:
|
17
|
+
#
|
18
|
+
# ```ruby
|
19
|
+
# target = Vips::Target.new_to_file('k2.jpg')
|
20
|
+
# image.write_to_target(target, '.jpg')
|
21
|
+
# ```
|
22
|
+
class Target < Vips::Connection
|
23
|
+
# The layout of the VipsRegion struct.
|
24
|
+
module TargetLayout
|
25
|
+
def self.included(base)
|
26
|
+
base.class_eval do
|
27
|
+
layout :parent, Vips::Connection::Struct
|
28
|
+
# rest opaque
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Struct < Vips::Connection::Struct
|
34
|
+
include TargetLayout
|
35
|
+
end
|
36
|
+
|
37
|
+
class ManagedStruct < Vips::Connection::ManagedStruct
|
38
|
+
include TargetLayout
|
39
|
+
end
|
40
|
+
|
41
|
+
# Create a new target to a file descriptor. File descriptors are
|
42
|
+
# small integers, for example 1 is stdout.
|
43
|
+
#
|
44
|
+
# Pass targets to {Image#write_to_target} to write images to
|
45
|
+
# them.
|
46
|
+
#
|
47
|
+
# @param descriptor [Integer] the file descriptor
|
48
|
+
# @return [Target] the new Vips::Target
|
49
|
+
def self.new_to_descriptor(descriptor)
|
50
|
+
ptr = Vips.vips_target_new_to_descriptor descriptor
|
51
|
+
raise Vips::Error if ptr.null?
|
52
|
+
|
53
|
+
Vips::Target.new ptr
|
54
|
+
end
|
55
|
+
|
56
|
+
# Create a new target to a file name.
|
57
|
+
#
|
58
|
+
# Pass targets to {Image#write_to_target} to write images to
|
59
|
+
# them.
|
60
|
+
#
|
61
|
+
# @param filename [String] the name of the file
|
62
|
+
# @return [Target] the new Vips::Target
|
63
|
+
def self.new_to_file(filename)
|
64
|
+
raise Vips::Error, "filename is nil" if filename.nil?
|
65
|
+
ptr = Vips.vips_target_new_to_file filename
|
66
|
+
raise Vips::Error if ptr.null?
|
67
|
+
|
68
|
+
Vips::Target.new ptr
|
69
|
+
end
|
70
|
+
|
71
|
+
# Create a new target to an area of memory.
|
72
|
+
#
|
73
|
+
# Pass targets to {Image#write_to_target} to write images to
|
74
|
+
# them.
|
75
|
+
#
|
76
|
+
# Once the image has been written, use {Object#get}`("blob")` to read out
|
77
|
+
# the data.
|
78
|
+
#
|
79
|
+
# @return [Target] the new Vips::Target
|
80
|
+
def self.new_to_memory
|
81
|
+
ptr = Vips.vips_target_new_to_memory
|
82
|
+
|
83
|
+
Vips::Target.new ptr
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,77 @@
|
|
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_target_custom_new, [], :pointer
|
12
|
+
end
|
13
|
+
|
14
|
+
# A target you can attach action signal handlers to to implememt
|
15
|
+
# custom output types.
|
16
|
+
#
|
17
|
+
# For example:
|
18
|
+
#
|
19
|
+
# ```ruby
|
20
|
+
# file = File.open "some/file/name", "wb"
|
21
|
+
# target = Vips::TargetCustom.new
|
22
|
+
# target.on_write { |bytes| file.write bytes }
|
23
|
+
# image.write_to_target target, ".png"
|
24
|
+
# ```
|
25
|
+
#
|
26
|
+
# (just an example -- of course in practice you'd use {Target#new_to_file}
|
27
|
+
# to write to a named file)
|
28
|
+
class TargetCustom < Vips::Target
|
29
|
+
module TargetCustomLayout
|
30
|
+
def self.included(base)
|
31
|
+
base.class_eval do
|
32
|
+
layout :parent, Vips::Target::Struct
|
33
|
+
# rest opaque
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Struct < Vips::Target::Struct
|
39
|
+
include TargetCustomLayout
|
40
|
+
end
|
41
|
+
|
42
|
+
class ManagedStruct < Vips::Target::ManagedStruct
|
43
|
+
include TargetCustomLayout
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
pointer = Vips.vips_target_custom_new
|
48
|
+
raise Vips::Error if pointer.null?
|
49
|
+
|
50
|
+
super pointer
|
51
|
+
end
|
52
|
+
|
53
|
+
# The block is executed to write data to the source. The interface is
|
54
|
+
# exactly as IO::write, ie. it should write the string and return the
|
55
|
+
# number of bytes written.
|
56
|
+
#
|
57
|
+
# @yieldparam bytes [String] Write these bytes to the file
|
58
|
+
# @yieldreturn [Integer] The number of bytes written, or -1 on error
|
59
|
+
def on_write &block
|
60
|
+
signal_connect "write" do |p, len|
|
61
|
+
chunk = p.get_bytes(0, len)
|
62
|
+
bytes_written = block.call chunk
|
63
|
+
chunk.clear
|
64
|
+
|
65
|
+
bytes_written
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# The block is executed at the end of write. It should do any necessary
|
70
|
+
# finishing action, such as closing a file.
|
71
|
+
def on_finish &block
|
72
|
+
signal_connect "finish" do
|
73
|
+
block.call
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/vips/version.rb
CHANGED