Module: Vips
- Extended by:
- FFI::Library
- Defined in:
- lib/vips.rb,
lib/vips.rb,
lib/vips/size.rb,
lib/vips/align.rb,
lib/vips/angle.rb,
lib/vips/image.rb,
lib/vips/image.rb,
lib/vips/access.rb,
lib/vips/coding.rb,
lib/vips/extend.rb,
lib/vips/kernel.rb,
lib/vips/object.rb,
lib/vips/region.rb,
lib/vips/source.rb,
lib/vips/target.rb,
lib/vips/angle45.rb,
lib/vips/methods.rb,
lib/vips/version.rb,
lib/vips/direction.rb,
lib/vips/operation.rb,
lib/vips/bandformat.rb,
lib/vips/blend_mode.rb,
lib/vips/connection.rb,
lib/vips/interesting.rb,
lib/vips/interpolate.rb,
lib/vips/mutableimage.rb,
lib/vips/sourcecustom.rb,
lib/vips/targetcustom.rb,
lib/vips/operationmath.rb,
lib/vips/interpretation.rb,
lib/vips/operationmath2.rb,
lib/vips/operationround.rb,
lib/vips/operationboolean.rb,
lib/vips/operationcomplex.rb,
lib/vips/compass_direction.rb,
lib/vips/operationcomplex2.rb,
lib/vips/operationcomplexget.rb,
lib/vips/operationrelational.rb
Overview
This module provides a binding for the libvips image processing library.
Example
require 'vips'
if ARGV.length < 2
raise "usage: #{$PROGRAM_NAME}: input-file output-file"
end
im = Vips::Image.new_from_file ARGV[0], access: :sequential
im *= [1, 2, 1]
mask = Vips::Image.new_from_array [
[-1, -1, -1],
[-1, 16, -1],
[-1, -1, -1]
], 8
im = im.conv mask, precision: :integer
im.write_to_file ARGV[1]
This example loads a file, boosts the green channel (I'm not sure why), sharpens the image, and saves it back to disc again.
Reading this example line by line, we have:
im = Vips::Image.new_from_file ARGV[0], access: :sequential
Image.new_from_file can load any image file supported by vips. In this
example, we will be accessing pixels top-to-bottom as we sweep through the
image reading and writing, so :sequential
access mode is best for us. The
default mode is :random
: this allows for full random access to image pixels,
but is slower and needs more memory. See Access
for full details
on the various modes available.
You can also load formatted images from memory buffers, create images that wrap C-style memory arrays, or make images from constants. Use Source and Image.new_from_source to load images from any data source, for example URIs.
The next line:
im *= [1, 2, 1]
Multiplying the image by an array constant uses one array element for each image band. This line assumes that the input image has three bands and will double the middle band. For RGB images, that's doubling green.
Next we have:
mask = Vips::Image.new_from_array [
[-1, -1, -1],
[-1, 16, -1],
[-1, -1, -1]
], 8
im = im.conv mask, precision: :integer
Image.new_from_array creates an image from an array constant. The 8 at the end sets the scale: the amount to divide the image by after integer convolution.
See the libvips API docs for vips_conv()
(the operation
invoked by Image#conv) for details on the convolution operator. By default,
it computes with a float mask, but :integer
is fine for this case, and is
much faster.
Finally:
im.write_to_file ARGV[1]
Image#write_to_file writes an image back to the filesystem. It can write any format supported by vips: the file type is set from the filename suffix. You can also write formatted images to memory buffers, or dump image data to a raw memory array.
Use Target and Image#write_to_target to write formatted images to any data sink, for example URIs.
How it works
The binding uses ruby-ffi to open the libvips shared library. When you call a method on the image class, it uses libvips introspection system (based on GObject) to search the library for an operation of that name, transforms the arguments to a form libvips can digest, and runs the operation.
This means ruby-vips always presents the API implemented by the libvips shared library. It should update itself as new features are added.
Automatic wrapping
ruby-vips
adds a Image.method_missing handler to Image and uses
it to look up vips operations. For example, the libvips operation add
, which
appears in C as vips_add()
, appears in Ruby as Image#add.
The operation's list of required arguments is searched and the first input
image is set to the value of self
. Operations which do not take an input
image, such as Image.black, appear as class methods. The remainder of
the arguments you supply in the function call are used to set the other
required input arguments. Any trailing keyword arguments are used to set
options on the operation.
The result is the required output argument if there is only one result, or an array of values if the operation produces several results. If the operation has optional output objects, they are returned as a final hash.
For example, Image#min, the vips operation that searches an image for the minimum value, has a large number of optional arguments. You can use it to find the minimum value like this:
min_value = image.min
You can ask it to return the position of the minimum with :x
and :y
.
min_value, opts = min x: true, y: true
x_pos = opts['x']
y_pos = opts['y']
Now x_pos
and y_pos
will have the coordinates of the minimum value.
There's actually a convenience method for this, Image#minpos.
You can also ask for the top n minimum, for example:
min_value, opts = min size: 10, x_array: true, y_array: true
x_pos = opts['x_array']
y_pos = opts['y_array']
Now x_pos
and y_pos
will be 10-element arrays.
Because operations are member functions and return the result image, you can chain them. For example, you can write:
result_image = image.real.cos
to calculate the cosine of the real part of a complex image. There are also a full set of arithmetic operator overloads, see below.
libvips types are also automatically wrapped. The override looks at the type
of argument required by the operation and converts the value you supply,
when it can. For example, Image#linear takes a VipsArrayDouble
as
an argument
for the set of constants to use for multiplication. You can supply this
value as an integer, a float, or some kind of compound object and it
will be converted for you. You can write:
result_image = image.linear 1, 3
result_image = image.linear 12.4, 13.9
result_image = image.linear [1, 2, 3], [4, 5, 6]
result_image = image.linear 1, [4, 5, 6]
And so on. A set of overloads are defined for Image#linear, see below.
It does a couple of more ambitious conversions. It will automatically convert
to and from the various vips types, like VipsBlob
and VipsArrayImage
. For
example, you can read the ICC profile out of an image like this:
profile = im.get_value "icc-profile-data"
and profile will be a byte array.
If an operation takes several input images, you can use a constant for all but one of them and the wrapper will expand the constant to an image for you. For example, Image#ifthenelse uses a condition image to pick pixels between a then and an else image:
result_image = condition_image.ifthenelse then_image, else_image
You can use a constant instead of either the then or the else parts and it will be expanded to an image for you. If you use a constant for both then and else, it will be expanded to match the condition image. For example:
result_image = condition_image.ifthenelse [0, 255, 0], [255, 0, 0]
Will make an image where true pixels are green and false pixels are red.
This is useful for Image#bandjoin, the thing to join two or more images up bandwise. You can write:
rgba = rgb.bandjoin 255
to append a constant 255 band to an image, perhaps to add an alpha channel. Of course you can also write:
result_image = image1.bandjoin image2
result_image = image1.bandjoin [image2, image3]
result_image = Vips::Image.bandjoin [image1, image2, image3]
result_image = image1.bandjoin [image2, 255]
and so on.
Logging
Libvips uses g_log() to log warning, debug, info and (some) error messages.
https://developer.gnome.org/glib/stable/glib-Message-Logging.html
You can disable warnings by defining the VIPS_WARNING
environment variable.
You can enable info output by defining VIPS_INFO
.
Exceptions
The wrapper spots errors from vips operations and raises the Error exception. You can catch it in the usual way.
Automatic YARD documentation
The bulk of these API docs are generated automatically by Yard.generate. It examines libvips and writes a summary of each operation and the arguments and options that that operation expects.
Use the C API # docs for more detail.
Enums
The libvips enums, such as VipsBandFormat
appear in ruby-vips as Symbols
like :uchar
. They are documented as a set of classes for convenience, see
BandFormat, for example.
Draw operations
There are two ways of calling the libvips draw operations, like Image#draw_circle and Image#draw_line.
First, you can use them like functions. For example:
y = x.draw_line 255, 0, 0, x.width, x.height
This will make a new image, y
, which is a copy of x
but with a line
drawn across it. x
is unchanged.
This is simple, but will be slow if you want to draw many lines, since ruby-vips will make a copy of the whole image each time.
You can use Image#mutate to make a MutableImage. This is an image which
is unshared and is only available inside the Image#mutate block. Within
this block, you can use !
versions of the draw operations to modify images
and avoid the copy. For example:
image = image.mutate do |mutable|
(0 ... 1).step(0.01) do |i|
mutable.draw_line! 255, mutable.width * i, 0, 0, mutable.height * (1 - i)
end
end
Now each Image#draw_line will directly modify the mutable image, saving the copy. This is much faster and needs much less memory.
Metadata read
Use Image#get_fields to get a list of the metadata fields that an image
supports. ICC profiles, for example, are in a field called
icc-profile-data
. Use vipsheader -a something.jpg
at the command-line
to see all the fields on an image.
Use Image#get_typeof to get the type of a field. Types are integers, with 0 meaning "no such field". Constants like GObject::GINT_TYPE are useful for testing field types.
You can read image metadata using Image#get. The field value is converted to a Ruby value in the obvious way.
Metadata write
You can also set and remove image metadata fields. Images are immutable, so you must make any changes inside a Image#mutate block. For example:
image = image.mutate do |mutable|
image.get_fields.each do |field|
mutable.remove! field unless field == "icc-profile-data"
end
end
To remove all metadata except the icc profile.
You can use MutableImage#set! to change the value of an existing field, and MutableImage#set_type! to create a new field with a specified type.
Progress
You can attach signal handlers to images to watch computation progress. For example:
image = Vips::Image.black 1, 100000
image.set_progress true
def progress_to_s(name, progress)
puts "#{name}:"
puts " run = #{progress[:run]}"
puts " eta = #{progress[:eta]}"
puts " tpels = #{progress[:tpels]}"
puts " npels = #{progress[:npels]}"
puts " percent = #{progress[:percent]}"
end
image.signal_connect :preeval do |progress|
progress_to_s("preeval", progress)
end
image.signal_connect :eval do |progress|
progress_to_s("eval", progress)
image.set_kill(true) if progress[:percent] > 50
end
image.signal_connect :posteval do |progress|
progress_to_s("posteval", progress)
end
image.avg
The :eval
signal will fire for every tile that is processed. You can stop
progress with Image#set_kill and processing will end with an exception.
User streams
You can make your own input and output stream objects with SourceCustom and TargetCustom. For example:
file = File.open "some/file", "rb"
source = Vips::SourceCustom.new
source.on_read { |length| file.read length }
image = Vips::Image.new_from_source source, "", access: "sequential"
Overloads
The wrapper defines the usual set of arithmetic, boolean and relational overloads on image. You can mix images, constants and lists of constants (almost) freely. For example, you can write:
result_image = ((image * [1, 2, 3]).abs < 128) | 4
Expansions
Some vips operators take an enum to select an action, for example Image#math can be used to calculate sine of every pixel like this:
result_image = image.math :sin
This is annoying, so the wrapper expands all these enums into separate members named after the enum. So you can write:
result_image = image.sin
Convenience functions
The wrapper defines a few extra useful utility functions: Image#get_value, Image#set_value, Image#bandsplit, Image#maxpos, Image#minpos, Image#median.
Defined Under Namespace
Modules: Yard Classes: Access, Align, Angle, Angle45, Argument, ArgumentClass, ArgumentClassPtr, ArgumentInstance, ArgumentInstancePtr, BandFormat, BlendMode, Coding, CompassDirection, Connection, Direction, Error, Extend, Image, IntStruct, Interesting, Interpolate, Interpretation, Introspect, Kernel, MutableImage, Object, ObjectClass, Operation, OperationBoolean, OperationComplex, OperationComplex2, OperationComplexget, OperationMath, OperationMath2, OperationRelational, OperationRound, Progress, Region, Size, SizeStruct, Source, SourceCustom, Target, TargetCustom
Constant Summary collapse
- LOG_DOMAIN =
we've already opened the libvips library
"VIPS"
- DEFAULT_CONCURRENCY =
Track the original default concurrency so we can reset to it.
vips_concurrency_get
- LIBRARY_VERSION =
Vips.version_string
- MAX_COORD =
libvips has this arbitrary number as a sanity-check upper bound on image size. It's sometimes useful to know when calculating scale factors.
10000000
- IMAGE_TYPE =
some handy gtypes
GObject.g_type_from_name "VipsImage"
- ARRAY_INT_TYPE =
GObject.g_type_from_name "VipsArrayInt"
- ARRAY_DOUBLE_TYPE =
GObject.g_type_from_name "VipsArrayDouble"
- ARRAY_IMAGE_TYPE =
GObject.g_type_from_name "VipsArrayImage"
- REFSTR_TYPE =
GObject.g_type_from_name "VipsRefString"
- BLOB_TYPE =
GObject.g_type_from_name "VipsBlob"
- BAND_FORMAT_TYPE =
Vips.vips_band_format_get_type
- INTERPRETATION_TYPE =
Vips.vips_interpretation_get_type
- CODING_TYPE =
Vips.vips_coding_get_type
- BLEND_MODE_TYPE =
nil
- VERSION =
"2.2.2"
Class Method Summary collapse
-
.at_least_libvips?(x, y) ⇒ Boolean
True if this is at least libvips x.y.
-
.block(operation_name, enabled) ⇒ Object
Block/unblock all operations in the libvips class hierarchy at specified operation_name and below.
-
.block_untrusted(enabled) ⇒ Object
Block/unblock all untrusted operations from running.
-
.cache_drop_all ⇒ Object
Drop the libvips operation cache.
-
.cache_max ⇒ Object
Get the maximum number of operations that libvips should cache.
-
.cache_max_files ⇒ Object
Get the maximum number of files libvips keeps open in the operation cache.
-
.cache_max_mem ⇒ Object
Get the maximum amount of memory that libvips uses for the operation cache.
-
.cache_print ⇒ Object
Print the libvips operation cache to stdout.
-
.cache_set_max(size) ⇒ Object
Set the maximum number of operations that libvips should cache.
-
.cache_set_max_files(size) ⇒ Object
Set the maximum number of files libvips should keep open in the operation cache.
-
.cache_set_max_mem(size) ⇒ Object
Set the maximum amount of memory that libvips should use for the operation cache.
-
.concurrency ⇒ Object
Get the size of libvips worker pools.
-
.concurrency_default ⇒ Object
Get the default size of libvips worker pools.
-
.concurrency_set(n) ⇒ Object
Set the size of each libvips worker pool.
-
.get_suffixes ⇒ [String]
Get a list of all supported file suffixes.
-
.leak_set(leak) ⇒ Object
Turn libvips leak testing on and off.
-
.set_debug(debug) ⇒ Object
Deprecated compatibility function.
-
.tracked_allocs ⇒ Object
Get the number of active allocations.
-
.tracked_files ⇒ Object
Get the number of open files.
-
.tracked_mem ⇒ Object
Get the number of bytes currently allocated via vips_malloc.
-
.tracked_mem_highwater ⇒ Object
Get the greatest number of bytes ever actively allocated via vips_malloc.
- .unified? ⇒ Boolean
-
.vector? ⇒ Boolean
Whether SIMD and the run-time compiler are enabled.
-
.vector_set(enabled) ⇒ Object
Enable or disable SIMD and the run-time compiler.
Class Method Details
.at_least_libvips?(x, y) ⇒ Boolean
True if this is at least libvips x.y
805 806 807 808 809 810 |
# File 'lib/vips.rb', line 805 def self.at_least_libvips?(x, y) major = version(0) minor = version(1) major > x || (major == x && minor >= y) end |
.block(operation_name, enabled) ⇒ Object
Block/unblock all operations in the libvips class hierarchy at specified operation_name and below.
For example this will block all loaders except JPEG
Vips.block("VipsForeignLoad", true); Vips.block("VipsForeignLoadJpeg", false)
Use vips -l
at the command-line to see the class hierarchy.
This call does nothing if the named operation is not found.
832 833 834 |
# File 'lib/vips.rb', line 832 def self.block(operation_name, enabled) vips_operation_block_set(operation_name, enabled) end |
.block_untrusted(enabled) ⇒ Object
Block/unblock all untrusted operations from running.
Use vips -l
at the command-line to see the class hierarchy and which operations are marked as untrusted.
818 819 820 |
# File 'lib/vips.rb', line 818 def self.block_untrusted(enabled) vips_block_untrusted_set(enabled) end |
.cache_drop_all ⇒ Object
Drop the libvips operation cache. Handy for leak tracking.
754 755 756 |
# File 'lib/vips.rb', line 754 def self.cache_drop_all # :nodoc: vips_cache_drop_all end |
.cache_max ⇒ Object
Get the maximum number of operations that libvips should cache.
712 713 714 |
# File 'lib/vips.rb', line 712 def self.cache_max vips_cache_get_max end |
.cache_max_files ⇒ Object
Get the maximum number of files libvips keeps open in the operation cache.
722 723 724 |
# File 'lib/vips.rb', line 722 def self.cache_max_files vips_cache_get_max_files end |
.cache_max_mem ⇒ Object
Get the maximum amount of memory that libvips uses for the operation cache.
717 718 719 |
# File 'lib/vips.rb', line 717 def self.cache_max_mem vips_cache_get_max_mem end |
.cache_print ⇒ Object
Print the libvips operation cache to stdout. Handy for debugging.
749 750 751 |
# File 'lib/vips.rb', line 749 def self.cache_print # :nodoc: vips_cache_print end |
.cache_set_max(size) ⇒ Object
Set the maximum number of operations that libvips should cache. Set 0 to disable the operation cache. The default is 1000.
728 729 730 731 |
# File 'lib/vips.rb', line 728 def self.cache_set_max size vips_cache_set_max size cache_max end |
.cache_set_max_files(size) ⇒ Object
Set the maximum number of files libvips should keep open in the operation cache. Set 0 to disable the operation cache. The default is 100.
743 744 745 746 |
# File 'lib/vips.rb', line 743 def self.cache_set_max_files size vips_cache_set_max_files size cache_max_files end |
.cache_set_max_mem(size) ⇒ Object
Set the maximum amount of memory that libvips should use for the operation cache. Set 0 to disable the operation cache. The default is 100mb.
735 736 737 738 |
# File 'lib/vips.rb', line 735 def self.cache_set_max_mem size vips_cache_set_max_mem size cache_max_mem end |
.concurrency ⇒ Object
Get the size of libvips worker pools. Defaults to the VIPS_CONCURRENCY env var or the number of hardware threads on your computer.
760 761 762 |
# File 'lib/vips.rb', line 760 def self.concurrency vips_concurrency_get end |
.concurrency_default ⇒ Object
Get the default size of libvips worker pools.
765 766 767 |
# File 'lib/vips.rb', line 765 def self.concurrency_default DEFAULT_CONCURRENCY end |
.concurrency_set(n) ⇒ Object
Set the size of each libvips worker pool. Max 1024 threads. Set to 1 to disable threading. Set to 0 or nil to reset to default.
771 772 773 774 775 |
# File 'lib/vips.rb', line 771 def self.concurrency_set n n = DEFAULT_CONCURRENCY if n.to_i == 0 vips_concurrency_set n concurrency end |
.get_suffixes ⇒ [String]
Get a list of all supported file suffixes.
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 |
# File 'lib/vips.rb', line 840 def self.get_suffixes # vips_foreign_get_suffixes() was added in libvips 8.8 return [] unless Vips.respond_to? :vips_foreign_get_suffixes array = Vips.vips_foreign_get_suffixes names = [] p = array until (q = p.read_pointer).null? suff = q.read_string GLib.g_free q names << suff unless names.include? suff p += FFI::Type::POINTER.size end GLib.g_free array names end |
.leak_set(leak) ⇒ Object
Turn libvips leak testing on and off. Handy for debugging ruby-vips, not very useful for user code.
674 675 676 |
# File 'lib/vips.rb', line 674 def self.leak_set leak vips_leak_set((leak ? 1 : 0)) end |
.set_debug(debug) ⇒ Object
Deprecated compatibility function.
Don't use this, instead change GLib::logger.level.
795 796 797 798 799 |
# File 'lib/vips.rb', line 795 def self.set_debug debug if debug GLib.logger.level = Logger::DEBUG end end |
.tracked_allocs ⇒ Object
Get the number of active allocations.
702 703 704 |
# File 'lib/vips.rb', line 702 def self.tracked_allocs vips_tracked_get_allocs end |
.tracked_files ⇒ Object
Get the number of open files.
707 708 709 |
# File 'lib/vips.rb', line 707 def self.tracked_files vips_tracked_get_files end |
.tracked_mem ⇒ Object
Get the number of bytes currently allocated via vips_malloc.
692 693 694 |
# File 'lib/vips.rb', line 692 def self.tracked_mem vips_tracked_get_mem end |
.tracked_mem_highwater ⇒ Object
Get the greatest number of bytes ever actively allocated via vips_malloc.
697 698 699 |
# File 'lib/vips.rb', line 697 def self.tracked_mem_highwater vips_tracked_get_mem_highwater end |
.unified? ⇒ Boolean
55 56 57 |
# File 'lib/vips.rb', line 55 def self.unified? @@is_unified end |
.vector? ⇒ Boolean
Whether SIMD and the run-time compiler are enabled. This can give a nice speed-up, but can also be unstable on some systems or with some versions of the run-time compiler.
780 781 782 |
# File 'lib/vips.rb', line 780 def self.vector? vips_vector_isenabled == 1 end |
.vector_set(enabled) ⇒ Object
Enable or disable SIMD and the run-time compiler. This can give a nice speed-up, but can also be unstable on some systems or with some versions of the run-time compiler.
787 788 789 790 |
# File 'lib/vips.rb', line 787 def self.vector_set enabled vips_vector_set_enabled(enabled ? 1 : 0) vector? end |