some work on the new Python binding
This commit is contained in:
parent
73465109b7
commit
39e92f8f1b
8
TODO
8
TODO
@ -1,3 +1,11 @@
|
||||
- python/* is too old, keep for reference, but we need to use the
|
||||
introspection stuff to get current gobject bindings
|
||||
|
||||
look at that brancg again
|
||||
|
||||
|
||||
|
||||
|
||||
- foreign docs come up as "VipsForeignSave", annoying, why?
|
||||
|
||||
- we can no longer have round brackets in filenames, argh
|
||||
|
@ -2,7 +2,7 @@ Experimental Python binding using ctypes
|
||||
|
||||
The current Python binding uses swig to wrap the C++ interface. This causes
|
||||
problems on Windows, since compiling all of the DLLs correctly to work with
|
||||
the various python binaries is painful, and makes the bainding very large.
|
||||
the various python binaries is painful, and makes the binding very large.
|
||||
|
||||
The idea here is to use ctypes to make a binding that's just Python and which
|
||||
directly wraps the C API. The new vips8 C API is much more wrapper-friendly,
|
||||
|
@ -5,6 +5,7 @@ import gc
|
||||
|
||||
import gobject
|
||||
|
||||
import vipsobject
|
||||
import vipsimage
|
||||
|
||||
logging.basicConfig(level = logging.DEBUG)
|
||||
@ -21,22 +22,34 @@ a = vipsimage.VipsImage('/home/john/pics/healthygirl.jpg')
|
||||
print 'width =', a.width()
|
||||
print 'height =', a.height()
|
||||
print 'bands =', a.bands()
|
||||
print 'format =', vipsimage.VipsBandFormat.name(a.format())
|
||||
print 'coding =', vipsimage.VipsCoding.name(a.coding())
|
||||
print 'interpretation =', vipsimage.VipsInterpretation.name(a.interpretation())
|
||||
print 'format = %d - %s' % (a.format(),
|
||||
vipsimage.VipsBandFormat.name(a.format()))
|
||||
print 'coding = %d - %s' % (a.coding(),
|
||||
vipsimage.VipsCoding.name(a.coding()))
|
||||
print 'interpretation = %d - %s' % (a.interpretation(),
|
||||
vipsimage.VipsInterpretation.name(a.interpretation()))
|
||||
print 'xres =', a.xres()
|
||||
print 'yres =', a.yres()
|
||||
print 'xoffset =', a.xoffset()
|
||||
print 'yoffset =', a.yoffset()
|
||||
|
||||
# should raise an error
|
||||
a = vipsimage.VipsImage('banana')
|
||||
try:
|
||||
a = vipsimage.VipsImage('banana')
|
||||
except vipsobject.VipsError, e:
|
||||
print 'caught VipsError'
|
||||
print '\tmessage =', e.message
|
||||
print '\tdetail =', e.detail
|
||||
|
||||
# try calling a vips8 method
|
||||
a = vipsimage.VipsImage('/home/john/pics/healthygirl.jpg')
|
||||
b = vipsimage.VipsImage('/home/john/pics/babe.jpg')
|
||||
c = a.add(b)
|
||||
|
||||
print 'c = ', c
|
||||
|
||||
c.write('/home/john/pics/x.v')
|
||||
|
||||
print 'starting shutdown ...'
|
||||
del a
|
||||
del b
|
||||
|
@ -9,6 +9,8 @@ GNU LESSER GENERAL PUBLIC LICENSE
|
||||
import logging
|
||||
import ctypes
|
||||
|
||||
import gobject
|
||||
|
||||
import vipsobject
|
||||
|
||||
# image enums
|
||||
@ -45,7 +47,6 @@ class VipsInterpretation:
|
||||
|
||||
@staticmethod
|
||||
def name(value):
|
||||
print currentclass
|
||||
return vipsobject.class_value(VipsInterpretation, value)
|
||||
|
||||
class VipsBandFormat:
|
||||
@ -102,15 +103,14 @@ vips_image_get_xres.restype = ctypes.c_double;
|
||||
vips_image_get_yres = libvips.vips_image_get_yres
|
||||
vips_image_get_yres.restype = ctypes.c_double;
|
||||
|
||||
vips_operation_new = libvips.vips_operation_new
|
||||
vips_operation_new.argtypes = [ctypes.c_char_p]
|
||||
vips_operation_new.restype = ctypes.c_void_p
|
||||
vips_operation_new.errcheck = vipsobject.check_pointer_return
|
||||
|
||||
def vips_call_instance(self, name, args):
|
||||
logging.debug('vipsimage: vips_call_instance name=%s, self=%s, args=%s' %
|
||||
(name, self, args))
|
||||
operation = vipsoperation.VipsOperation(name)
|
||||
operation = vips_operation_new(name)
|
||||
vipsobject.vips_object_print(operation)
|
||||
vipsobject.vips_argument_map(operation,
|
||||
vipsobject.VipsArgumentMapFn(show_args),None, None)
|
||||
|
||||
class VipsImage(vipsobject.VipsObject):
|
||||
"""Manipulate a libvips image."""
|
||||
|
@ -20,6 +20,26 @@ import finalizable
|
||||
libvips = ctypes.CDLL('libvips.so.15')
|
||||
libvips.vips_init(sys.argv[0])
|
||||
|
||||
vips_object_print = libvips.vips_object_print
|
||||
vips_object_print.argtypes = [ctypes.c_void_p]
|
||||
vips_object_print.restype = None
|
||||
|
||||
# in C:
|
||||
# typedef void *(*VipsArgumentMapFn)( VipsObject *,
|
||||
# GParamSpec *, VipsArgumentClass *, VipsArgumentInstance *,
|
||||
# void *a, void *b );
|
||||
VipsArgumentMapFn = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p,
|
||||
ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p,
|
||||
ctypes.c_void_p, ctypes.c_void_p)
|
||||
vips_argument_map = libvips.vips_argument_map
|
||||
vips_argument_map.argtypes = [ctypes.c_void_p, VipsArgumentMapFn,
|
||||
ctypes.c_void_p, ctypes.c_void_p]
|
||||
vips_argument_map.restype = ctypes.c_void_p
|
||||
|
||||
g_param_spec_get_name = libvips.g_param_spec_get_name
|
||||
g_param_spec_get_name.argtypes = [ctypes.c_void_p]
|
||||
g_param_spec_get_name.restype = ctypes.c_char_p
|
||||
|
||||
# given a class and value, search for a class member with that value
|
||||
# handy for enum classes, use to turn numbers to strings
|
||||
def class_value(classobject, value):
|
||||
@ -45,7 +65,7 @@ class VipsError(Exception):
|
||||
logging.debug('vipsobject: Error: %s %s', self.message, self.detail)
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s' %(self.message, self.detail)
|
||||
return '%s %s' % (self.message, self.detail)
|
||||
|
||||
# handy checkers, assign to errcheck
|
||||
def check_int_return(result, func, args):
|
||||
|
46
python/vipsoperation.py
Normal file
46
python/vipsoperation.py
Normal file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""This module wraps up libvips in a less awful interface.
|
||||
|
||||
Author: J.Cupitt
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
"""
|
||||
|
||||
import logging
|
||||
import ctypes
|
||||
|
||||
import gobject
|
||||
|
||||
import vipsobject
|
||||
|
||||
libvips = vipsobject.libvips
|
||||
|
||||
vips_operation_new = libvips.vips_operation_new
|
||||
vips_operation_new.argtypes = [ctypes.c_char_p]
|
||||
vips_operation_new.restype = ctypes.c_void_p
|
||||
vips_operation_new.errcheck = vipsobject.check_pointer_return
|
||||
|
||||
def show_args(operation, pspec, arg_class, arg_instance, a, b):
|
||||
name = vipsobject.g_param_spec_get_name(pspec)
|
||||
|
||||
def vips_call_instance(self, name, args):
|
||||
logging.debug('vipsimage: vips_call_instance name=%s, self=%s, args=%s' %
|
||||
(name, self, args))
|
||||
operation = vips_operation_new(name)
|
||||
vipsobject.vips_object_print(operation)
|
||||
vipsobject.vips_argument_map(operation,
|
||||
vipsobject.VipsArgumentMapFn(show_args),None, None)
|
||||
|
||||
class VipsOperation(vipsobject.VipsObject):
|
||||
"""Call a libvips operation."""
|
||||
|
||||
def __init__(self, name):
|
||||
logging.debug('vipsoperation: init %s', name)
|
||||
|
||||
vipsobject.VipsObject.__init__(self)
|
||||
|
||||
self.vipsobject = vips_operation_new(name)
|
||||
|
||||
self.enable_finalize()
|
||||
|
||||
def call
|
Loading…
Reference in New Issue
Block a user