mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add DrawingWand to ImageMagick API
This commit is contained in:
parent
34d427dfd5
commit
07d3e42cda
@ -7,14 +7,41 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
|
||||
from calibre.constants import plugins
|
||||
from calibre.constants import plugins, filesystem_encoding
|
||||
|
||||
_magick, _merr = plugins['magick']
|
||||
|
||||
if _magick is None:
|
||||
raise RuntimeError('Failed to load ImageMagick: '+_merr)
|
||||
|
||||
class Image(_magick.Image):
|
||||
_gravity_map = dict([(getattr(_magick, x), x) for x in dir(_magick) if
|
||||
x.endswith('Gravity')])
|
||||
|
||||
class DrawingWand(_magick.DrawingWand): # {{{
|
||||
|
||||
@dynamic_property
|
||||
def font(self):
|
||||
def fget(self):
|
||||
return self.font_.decode(filesystem_encoding, 'replace').lower()
|
||||
def fset(self, val):
|
||||
if isinstance(val, unicode):
|
||||
val = val.encode(filesystem_encoding)
|
||||
self.font_ = str(val)
|
||||
return property(fget=fget, fset=fset, doc=_magick.DrawingWand.font_.__doc__)
|
||||
|
||||
@dynamic_property
|
||||
def gravity(self):
|
||||
def fget(self):
|
||||
val = self.gravity_
|
||||
return _gravity_map[val]
|
||||
def fset(self, val):
|
||||
val = getattr(_magick, str(val))
|
||||
self.gravity_ = val
|
||||
return property(fget=fget, fset=fset, doc=_magick.DrawingWand.gravity_.__doc__)
|
||||
|
||||
# }}}
|
||||
|
||||
class Image(_magick.Image): # {{{
|
||||
|
||||
def load(self, data):
|
||||
return _magick.Image.load(self, bytes(data))
|
||||
@ -70,6 +97,8 @@ class Image(_magick.Image):
|
||||
raise ValueError('left and/or top out of bounds')
|
||||
_magick.Image.compose(self, img, int(left), int(top), op)
|
||||
|
||||
# }}}
|
||||
|
||||
def create_canvas(width, height, bgcolor):
|
||||
canvas = Image()
|
||||
canvas.create_canvas(int(width), int(height), str(bgcolor))
|
||||
|
@ -49,7 +49,7 @@ def get_value(const):
|
||||
|
||||
def main():
|
||||
constants = []
|
||||
for x in ('resample', 'image', 'draw', 'distort', 'composite'):
|
||||
for x in ('resample', 'image', 'draw', 'distort', 'composite', 'geometry'):
|
||||
constants += list(parse_enums('magick/%s.h'%x))
|
||||
base = os.path.dirname(__file__)
|
||||
constants = [
|
||||
|
@ -16,6 +16,220 @@ PyObject* magick_set_exception(MagickWand *wand) {
|
||||
}
|
||||
// }}}
|
||||
|
||||
// DrawingWand object definition {{{
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
// Type-specific fields go here.
|
||||
DrawingWand *wand;
|
||||
|
||||
} magick_DrawingWand;
|
||||
|
||||
static void
|
||||
magick_DrawingWand_dealloc(magick_DrawingWand* self)
|
||||
{
|
||||
if (self->wand != NULL) self->wand = DestroyDrawingWand(self->wand);
|
||||
self->ob_type->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
magick_DrawingWand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
magick_DrawingWand *self;
|
||||
|
||||
self = (magick_DrawingWand *)type->tp_alloc(type, 0);
|
||||
if (self != NULL) {
|
||||
self->wand = NewDrawingWand();
|
||||
if (self->wand == NULL || self->wand < 0) {
|
||||
PyErr_SetString(PyExc_Exception, "Failed to allocate wand.");
|
||||
self->wand = NULL;
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
// DrawingWand.font {{{
|
||||
static PyObject *
|
||||
magick_DrawingWand_font_getter(magick_DrawingWand *self, void *closure) {
|
||||
const char *fp;
|
||||
fp = DrawGetFont(self->wand);
|
||||
return Py_BuildValue("s", fp);
|
||||
}
|
||||
|
||||
static int
|
||||
magick_DrawingWand_font_setter(magick_DrawingWand *self, PyObject *val, void *closure) {
|
||||
char *fmt;
|
||||
|
||||
if (val == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete DrawingWand font");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fmt = PyString_AsString(val);
|
||||
if (fmt == NULL) return -1;
|
||||
|
||||
if (!DrawSetFont(self->wand, fmt)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Unknown font");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// DrawingWand.font_size {{{
|
||||
static PyObject *
|
||||
magick_DrawingWand_fontsize_getter(magick_DrawingWand *self, void *closure) {
|
||||
return Py_BuildValue("d", DrawGetFontSize(self->wand));
|
||||
}
|
||||
|
||||
static int
|
||||
magick_DrawingWand_fontsize_setter(magick_DrawingWand *self, PyObject *val, void *closure) {
|
||||
if (val == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete DrawingWand fontsize");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!PyFloat_Check(val)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Font size must be a float");
|
||||
return -1;
|
||||
}
|
||||
|
||||
DrawSetFontSize(self->wand, PyFloat_AsDouble(val));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// DrawingWand.text_antialias {{{
|
||||
static PyObject *
|
||||
magick_DrawingWand_textantialias_getter(magick_DrawingWand *self, void *closure) {
|
||||
return PyBool_FromLong((long)DrawGetTextAntialias(self->wand));
|
||||
}
|
||||
|
||||
static int
|
||||
magick_DrawingWand_textantialias_setter(magick_DrawingWand *self, PyObject *val, void *closure) {
|
||||
if (val == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete DrawingWand textantialias");
|
||||
return -1;
|
||||
}
|
||||
DrawSetTextAntialias(self->wand, (MagickBooleanType)PyObject_IsTrue(val));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// DrawingWand.gravity {{{
|
||||
static PyObject *
|
||||
magick_DrawingWand_gravity_getter(magick_DrawingWand *self, void *closure) {
|
||||
return Py_BuildValue("n", DrawGetGravity(self->wand));
|
||||
}
|
||||
|
||||
static int
|
||||
magick_DrawingWand_gravity_setter(magick_DrawingWand *self, PyObject *val, void *closure) {
|
||||
GravityType grav;
|
||||
|
||||
if (val == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete DrawingWand gravity");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!PyInt_Check(val)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Gravity must be an integer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
grav = PyInt_AsSsize_t(val);
|
||||
|
||||
DrawSetGravity(self->wand, grav);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
// DrawingWand attr list {{{
|
||||
static PyMethodDef magick_DrawingWand_methods[] = {
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyGetSetDef magick_DrawingWand_getsetters[] = {
|
||||
{(char *)"font_",
|
||||
(getter)magick_DrawingWand_font_getter, (setter)magick_DrawingWand_font_setter,
|
||||
(char *)"DrawingWand font path. Absolute path to font file.",
|
||||
NULL},
|
||||
|
||||
{(char *)"font_size",
|
||||
(getter)magick_DrawingWand_fontsize_getter, (setter)magick_DrawingWand_fontsize_setter,
|
||||
(char *)"DrawingWand fontsize",
|
||||
NULL},
|
||||
|
||||
{(char *)"text_antialias",
|
||||
(getter)magick_DrawingWand_textantialias_getter, (setter)magick_DrawingWand_textantialias_setter,
|
||||
(char *)"DrawingWand text antialias",
|
||||
NULL},
|
||||
|
||||
{(char *)"gravity_",
|
||||
(getter)magick_DrawingWand_gravity_getter, (setter)magick_DrawingWand_gravity_setter,
|
||||
(char *)"DrawingWand gravity",
|
||||
NULL},
|
||||
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
// }}}
|
||||
|
||||
static PyTypeObject magick_DrawingWandType = { // {{{
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /*ob_size*/
|
||||
"magick.DrawingWand", /*tp_name*/
|
||||
sizeof(magick_DrawingWand), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
(destructor)magick_DrawingWand_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash */
|
||||
0, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
"DrawingWand", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
magick_DrawingWand_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
magick_DrawingWand_getsetters, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
magick_DrawingWand_new, /* tp_new */
|
||||
}; // }}}
|
||||
|
||||
|
||||
// }}}
|
||||
|
||||
// Image object definition {{{
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
@ -44,7 +258,7 @@ magick_Image_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
if (self != NULL) {
|
||||
self->wand = NewMagickWand();
|
||||
if (self->wand == NULL || self->wand < 0) {
|
||||
PyErr_SetString(PyExc_Exception, "Failed to allocate wand. Did you initialize ImageMgick?");
|
||||
PyErr_SetString(PyExc_Exception, "Failed to allocate wand.");
|
||||
self->wand = NULL;
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
@ -140,8 +354,8 @@ magick_Image_size_setter(magick_Image *self, PyObject *val, void *closure) {
|
||||
MagickBooleanType res;
|
||||
|
||||
if (val == NULL) {
|
||||
return -1;
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete image size");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!PySequence_Check(val) || PySequence_Length(val) < 4) {
|
||||
@ -189,8 +403,8 @@ magick_Image_format_setter(magick_Image *self, PyObject *val, void *closure) {
|
||||
char *fmt;
|
||||
|
||||
if (val == NULL) {
|
||||
return -1;
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete image format");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fmt = PyString_AsString(val);
|
||||
@ -361,12 +575,16 @@ initmagick(void)
|
||||
|
||||
if (PyType_Ready(&magick_ImageType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&magick_DrawingWandType) < 0)
|
||||
return;
|
||||
|
||||
m = Py_InitModule3("magick", magick_methods,
|
||||
"Wrapper for the ImageMagick imaging library");
|
||||
|
||||
Py_INCREF(&magick_ImageType);
|
||||
PyModule_AddObject(m, "Image", (PyObject *)&magick_ImageType);
|
||||
Py_INCREF(&magick_DrawingWandType);
|
||||
PyModule_AddObject(m, "DrawingWand", (PyObject *)&magick_DrawingWandType);
|
||||
|
||||
magick_add_module_constants(m);
|
||||
MagickWandGenesis();
|
||||
|
@ -226,4 +226,41 @@ static void magick_add_module_constants(PyObject *m) {
|
||||
PyModule_AddIntConstant(m, "LinearDodgeCompositeOp", 61);
|
||||
PyModule_AddIntConstant(m, "LinearBurnCompositeOp", 62);
|
||||
PyModule_AddIntConstant(m, "MathematicsCompositeOp", 63);
|
||||
PyModule_AddIntConstant(m, "NoValue", 0);
|
||||
PyModule_AddIntConstant(m, "XValue", 1);
|
||||
PyModule_AddIntConstant(m, "XiValue", 1);
|
||||
PyModule_AddIntConstant(m, "YValue", 2);
|
||||
PyModule_AddIntConstant(m, "PsiValue", 2);
|
||||
PyModule_AddIntConstant(m, "WidthValue", 4);
|
||||
PyModule_AddIntConstant(m, "RhoValue", 4);
|
||||
PyModule_AddIntConstant(m, "HeightValue", 8);
|
||||
PyModule_AddIntConstant(m, "SigmaValue", 8);
|
||||
PyModule_AddIntConstant(m, "ChiValue", 16);
|
||||
PyModule_AddIntConstant(m, "XiNegative", 32);
|
||||
PyModule_AddIntConstant(m, "XNegative", 32);
|
||||
PyModule_AddIntConstant(m, "PsiNegative", 64);
|
||||
PyModule_AddIntConstant(m, "YNegative", 64);
|
||||
PyModule_AddIntConstant(m, "ChiNegative", 128);
|
||||
PyModule_AddIntConstant(m, "PercentValue", 4096);
|
||||
PyModule_AddIntConstant(m, "AspectValue", 8192);
|
||||
PyModule_AddIntConstant(m, "NormalizeValue", 8192);
|
||||
PyModule_AddIntConstant(m, "LessValue", 16384);
|
||||
PyModule_AddIntConstant(m, "GreaterValue", 32768);
|
||||
PyModule_AddIntConstant(m, "MinimumValue", 65536);
|
||||
PyModule_AddIntConstant(m, "CorrelateNormalizeValue", 65536);
|
||||
PyModule_AddIntConstant(m, "AreaValue", 131072);
|
||||
PyModule_AddIntConstant(m, "DecimalValue", 262144);
|
||||
PyModule_AddIntConstant(m, "AllValues", 2147483647);
|
||||
PyModule_AddIntConstant(m, "UndefinedGravity", 0);
|
||||
PyModule_AddIntConstant(m, "ForgetGravity", 0);
|
||||
PyModule_AddIntConstant(m, "NorthWestGravity", 1);
|
||||
PyModule_AddIntConstant(m, "NorthGravity", 2);
|
||||
PyModule_AddIntConstant(m, "NorthEastGravity", 3);
|
||||
PyModule_AddIntConstant(m, "WestGravity", 4);
|
||||
PyModule_AddIntConstant(m, "CenterGravity", 5);
|
||||
PyModule_AddIntConstant(m, "EastGravity", 6);
|
||||
PyModule_AddIntConstant(m, "SouthWestGravity", 7);
|
||||
PyModule_AddIntConstant(m, "SouthGravity", 8);
|
||||
PyModule_AddIntConstant(m, "SouthEastGravity", 9);
|
||||
PyModule_AddIntConstant(m, "StaticGravity", 10);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user