Class: Vips::Operation
- Inherits:
-
Object
- Object
- GObject::GObject
- Object
- Vips::Operation
- Defined in:
- lib/vips/operation.rb
Defined Under Namespace
Modules: OperationLayout Classes: ManagedStruct, Struct
Class Method Summary collapse
-
.call(name, supplied, optional = {}, option_string = "") ⇒ Object
This is the public entry point for the vips binding.
-
.flat_find(object, &block) ⇒ Object
Search an object for the first element to match a predicate.
-
.imageize(match_image, value) ⇒ Object
expand a constant into an image.
Instance Method Summary collapse
- #argument_map(&block) ⇒ Object
- #build ⇒ Object
-
#initialize(value) ⇒ Operation
constructor
A new instance of Operation.
-
#set(name, value, match_image, flags, gtype) ⇒ Object
set an operation argument, expanding constants and copying images as required.
Methods inherited from Object
#get, #get_pspec, #get_typeof, #get_typeof_error, print_all, #signal_connect
Methods inherited from GObject::GObject
#ffi_managed_struct, ffi_managed_struct, ffi_struct, #ffi_struct
Constructor Details
#initialize(value) ⇒ Operation
Returns a new instance of Operation.
175 176 177 178 179 180 181 182 183 184 |
# File 'lib/vips/operation.rb', line 175 def initialize value # allow init with a pointer so we can wrap the return values from # things like _build if value.is_a? String value = Vips::vips_operation_new value raise Vips::Error if value.null? end super value end |
Class Method Details
.call(name, supplied, optional = {}, option_string = "") ⇒ Object
This is the public entry point for the vips binding. call will run any vips operation, for example:
out = Vips::Operation.call "black", [100, 100], {:bands => 12}
will call the C function
vips_black( &out, 100, 100, "bands", 12, NULL );
There are Image#method_missing hooks which will run call for you on Image for undefined instance or class methods. So you can also write:
out = Vips::Image.black 100, 100, bands: 12
Or perhaps:
x = Vips::Image.black 100, 100
y = x.invert
to run the vips_invert()
operator.
There are also a set of operator overloads and some convenience functions, see Image.
If the operator needs a vector constant, call will turn a scalar
into a
vector for you. So for x.linear a, b
, which calculates
x * a + b
where a
and b
are vector constants, you can write:
x = Vips::Image.black 100, 100, bands: 3
y = x.linear 1, 2
y = x.linear [1], 4
y = x.linear [1, 2, 3], 4
or any other combination. The operator overloads use this facility to support all the variations on:
x = Vips::Image.black 100, 100, bands: 3
y = x * 2
y = x + [1,2,3]
y = x % [1]
Similarly, wherever an image is required, you can use a constant. The constant will be expanded to an image matching the first input image argument. For example, you can write:
x = Vips::Image.black 100, 100, bands: 3
y = x.bandjoin 255
to add an extra band to the image where each pixel in the new band has the constant value 255.
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
# File 'lib/vips/operation.rb', line 321 def self.call name, supplied, optional = {}, option_string = "" GLib::logger.debug("Vips::VipsOperation.call") { "name = #{name}, supplied = #{supplied}, " + "optional = #{optional}, option_string = #{option_string}" } introspect = Introspect.get name required_input = introspect.required_input required_output = introspect.required_output optional_input = introspect.optional_input optional_output = introspect.optional_output unless supplied.is_a? Array raise Vips::Error, "unable to call #{name}: " + "argument array is not an array" end unless optional.is_a? Hash raise Vips::Error, "unable to call #{name}: " + "optional arguments are not a hash" end if supplied.length != required_input.length raise Vips::Error, "unable to call #{name}: " + "you supplied #{supplied.length} arguments, " + "but operation needs " + "#{required_input.length}." end # all supplied_optional keys should be in optional_input or # optional_output optional.each do |key, _value| arg_name = key.to_s unless optional_input.has_key?(arg_name) || optional_output.has_key?(arg_name) raise Vips::Error, "unable to call #{name}: " + "unknown option #{arg_name}" end end # the first image arg is the thing we expand constants to match ... # we need to find it # # look inside array and hash arguments, since we may be passing an # array of images match_image = flat_find(supplied) { |value| value.is_a? Image } op = Operation.new name # set any string args first so they can't be overridden if option_string != nil if Vips::vips_object_set_from_string(op, option_string) != 0 raise Vips::Error end end # set all required inputs required_input.each_index do |i| details = required_input[i] arg_name = details[:arg_name] flags = details[:flags] gtype = details[:gtype] value = supplied[i] op.set arg_name, value, match_image, flags, gtype end # set all optional inputs optional.each do |key, value| next if value.nil? arg_name = key.to_s if optional_input.has_key? arg_name details = optional_input[arg_name] flags = details[:flags] gtype = details[:gtype] op.set arg_name, value, match_image, flags, gtype end end op = op.build # get all required results result = [] required_output.each do |details| result << op.get(details[:arg_name]) end # fetch all optional ones optional_results = {} optional.each do |key, _value| arg_name = key.to_s if optional_output.has_key? arg_name optional_results[arg_name] = op.get arg_name end end result << optional_results if optional_results != {} if result.length == 1 result = result.first elsif result.length == 0 result = nil end GLib::logger.debug("Vips::Operation.call") { "result = #{result}" } Vips::vips_object_unref_outputs op return result end |
.flat_find(object, &block) ⇒ Object
Search an object for the first element to match a predicate. Search inside subarrays and sub-hashes. Equlvalent to x.flatten.find{}.
206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/vips/operation.rb', line 206 def self.flat_find object, &block if object.respond_to? :each object.each do |x| result = flat_find x, &block return result if result != nil end else return object if yield object end return nil end |
.imageize(match_image, value) ⇒ Object
expand a constant into an image
220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/vips/operation.rb', line 220 def self.imageize match_image, value return value if value.is_a? Image # 2D array values become tiny 2D images # if there's nothing to match to, we also make a 2D image if (value.is_a?(Array) && value[0].is_a?(Array)) || match_image == nil return Image.new_from_array value else # we have a 1D array ... use that as a pixel constant and # expand to match match_image return match_image.new_from_image value end end |
Instance Method Details
#argument_map(&block) ⇒ Object
196 197 198 199 200 201 202 |
# File 'lib/vips/operation.rb', line 196 def argument_map &block fn = Proc.new do |_op, pspec, argument_class, argument_instance, _a, _b| block.call pspec, argument_class, argument_instance end Vips::vips_argument_map self, fn, nil, nil end |
#build ⇒ Object
186 187 188 189 190 191 192 193 194 |
# File 'lib/vips/operation.rb', line 186 def build op = Vips::vips_cache_operation_build self if op.null? Vips::vips_object_unref_outputs self raise Vips::Error end return Operation.new op end |
#set(name, value, match_image, flags, gtype) ⇒ Object
set an operation argument, expanding constants and copying images as required
237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/vips/operation.rb', line 237 def set name, value, match_image, flags, gtype if gtype == IMAGE_TYPE value = Operation::imageize match_image, value if (flags & ARGUMENT_MODIFY) != 0 # make sure we have a unique copy value = value.copy.copy_memory end elsif gtype == ARRAY_IMAGE_TYPE value = value.map { |x| Operation::imageize match_image, x } end super name, value end |