ctypes based wrapper for ImageMagick

Achim | python | Tuesday, December 25th, 2007

Due to the still existing demand for python bindings for ImageMagick I have created PythonMagickWand which is based on ctypes. It’s a very early version, but should work to resize images for example. Here is a snipped from the doctest:

>>> from PythonMagickWand import *

After that, you have to initialize MagickWand. This call might be
moved to the PythonMagickWand module, but i have to check if there
are poblems with multiple calls to this method or how to handle that.

>>> MagickWandGenesis()

Now we are ready to create a new wand

>>> wand = NewMagickWand()

and to load an image from a file.

>>> MagickReadImage(wand,”sample.jpg”) #doctest: +ELLIPSIS

Let’s resize the image

>>> MagickScaleImage(wand,200,200) #doctest: +ELLIPSIS

and save it to a new file.

>>> MagickWriteImage(wand,”out.png”) #doctest: +ELLIPSIS

If you don’t work on Mac OS X with macport, you will have to adjust the path to the ImageMagick library. I’ll fix this in the future. For more details see the doctests or execute “pydoc PythonMagickWand”.

19 Comments »

  1. linux:
    _magick = ctypes.CDLL(’/usr/lib/libWand.so.9′)

    >>> from PythonMagickWand import *
    /usr/lib/libWand.so.9: undefined symbol: MagickSetIteratorIndex
    /usr/lib/libWand.so.9: undefined symbol: MagickGetIteratorIndex
    /usr/lib/libWand.so.9: undefined symbol: MagickGetExceptionType
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageOrientation
    /usr/lib/libWand.so.9: undefined symbol: MagickOptimizeImageLayers
    /usr/lib/libWand.so.9: undefined symbol: MagickMergeImageLayers
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageClipMask
    /usr/lib/libWand.so.9: undefined symbol: MagickCompareImageLayers
    /usr/lib/libWand.so.9: undefined symbol: MagickVignetteImage
    /usr/lib/libWand.so.9: undefined symbol: MagickUniqueImageColors
    /usr/lib/libWand.so.9: undefined symbol: MagickTransverseImage
    /usr/lib/libWand.so.9: undefined symbol: MagickTransposeImage
    /usr/lib/libWand.so.9: undefined symbol: MagickSketchImage
    /usr/lib/libWand.so.9: undefined symbol: MagickShadeImage
    /usr/lib/libWand.so.9: undefined symbol: MagickResetImagePage
    /usr/lib/libWand.so.9: undefined symbol: MagickSetImageOrientation
    /usr/lib/libWand.so.9: undefined symbol: MagickSetImageOpacity
    /usr/lib/libWand.so.9: undefined symbol: MagickSetImageMatte
    /usr/lib/libWand.so.9: undefined symbol: MagickSetImageInterpolateMethod
    /usr/lib/libWand.so.9: undefined symbol: MagickSetImageClipMask
    /usr/lib/libWand.so.9: undefined symbol: MagickSetImageAlphaChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickSegmentImage
    /usr/lib/libWand.so.9: undefined symbol: MagickRecolorImage
    /usr/lib/libWand.so.9: undefined symbol: MagickRandomThresholdImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickRandomThresholdImage
    /usr/lib/libWand.so.9: undefined symbol: MagickPolaroidImage
    /usr/lib/libWand.so.9: undefined symbol: MagickPingImageFile
    /usr/lib/libWand.so.9: undefined symbol: MagickPingImageBlob
    /usr/lib/libWand.so.9: undefined symbol: MagickPaintOpaqueImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickPaintFloodfillImage
    /usr/lib/libWand.so.9: undefined symbol: MagickOrderedPosterizeImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickOrderedPosterizeImage
    /usr/lib/libWand.so.9: undefined symbol: MagickNormalizeImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickLinearStretchImage
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageRange
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageLength
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageMatte
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageChannelRange
    /usr/lib/libWand.so.9: undefined symbol: MagickExtentImage
    /usr/lib/libWand.so.9: undefined symbol: MagickEqualizeImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickDistortImage
    /usr/lib/libWand.so.9: undefined symbol: MagickContrastStretchImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickContrastStretchImage
    /usr/lib/libWand.so.9: undefined symbol: MagickCompositeImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickClutImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickClutImage
    /usr/lib/libWand.so.9: undefined symbol: MagickClipImagePath
    /usr/lib/libWand.so.9: undefined symbol: MagickAddNoiseImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickAdaptiveSharpenImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickAdaptiveSharpenImage
    /usr/lib/libWand.so.9: undefined symbol: MagickAdaptiveResizeImage
    /usr/lib/libWand.so.9: undefined symbol: MagickAdaptiveBlurImageChannel
    /usr/lib/libWand.so.9: undefined symbol: MagickAdaptiveBlurImage
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageInterpolateMethod
    /usr/lib/libWand.so.9: undefined symbol: MagickDestroyImage
    /usr/lib/libWand.so.9: undefined symbol: MagickGetBackgroundColor
    /usr/lib/libWand.so.9: undefined symbol: MagickSetSizeOffset
    /usr/lib/libWand.so.9: undefined symbol: MagickSetPointsize
    /usr/lib/libWand.so.9: undefined symbol: MagickSetOrientation
    /usr/lib/libWand.so.9: undefined symbol: MagickSetInterpolateMethod
    /usr/lib/libWand.so.9: undefined symbol: MagickSetImageProperty
    /usr/lib/libWand.so.9: undefined symbol: MagickSetGravity
    /usr/lib/libWand.so.9: undefined symbol: MagickSetFont
    /usr/lib/libWand.so.9: undefined symbol: MagickSetDepth
    /usr/lib/libWand.so.9: undefined symbol: MagickSetAntialias
    /usr/lib/libWand.so.9: undefined symbol: MagickGetSizeOffset
    /usr/lib/libWand.so.9: undefined symbol: MagickGetAntialias
    /usr/lib/libWand.so.9: undefined symbol: MagickDeleteImageProperty
    /usr/lib/libWand.so.9: undefined symbol: MagickDeleteOption
    /usr/lib/libWand.so.9: undefined symbol: MagickGetInterpolateMethod
    /usr/lib/libWand.so.9: undefined symbol: MagickGetType
    /usr/lib/libWand.so.9: undefined symbol: MagickGetGravity
    /usr/lib/libWand.so.9: undefined symbol: MagickGetPointsize
    /usr/lib/libWand.so.9: undefined symbol: MagickGetOptions
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageProperties
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageProperty
    /usr/lib/libWand.so.9: undefined symbol: MagickGetImageProfiles
    /usr/lib/libWand.so.9: undefined symbol: MagickGetFont
    /usr/lib/libWand.so.9: undefined symbol: DrawResetVectorGraphics
    /usr/lib/libWand.so.9: undefined symbol: DrawGetExceptionType
    /usr/lib/libWand.so.9: undefined symbol: PixelSetMagickColor
    /usr/lib/libWand.so.9: undefined symbol: PixelSetColorFromWand
    /usr/lib/libWand.so.9: undefined symbol: ClonePixelWands
    /usr/lib/libWand.so.9: undefined symbol: ClonePixelWand
    /usr/lib/libWand.so.9: undefined symbol: IsMagickTrue
    /usr/lib/libWand.so.9: undefined symbol: MagickOpenStream
    /usr/lib/libWand.so.9: undefined symbol: ListMagickOptions
    /usr/lib/libWand.so.9: undefined symbol: RelinquishMagickMatrix
    /usr/lib/libWand.so.9: undefined symbol: AcquireMagickMatrix
    /usr/lib/libWand.so.9: undefined symbol: MagickCoreTerminus
    /usr/lib/libWand.so.9: undefined symbol: MagickCoreGenesis
    /usr/lib/libWand.so.9: undefined symbol: FormatMagickCaption
    /usr/lib/libWand.so.9: undefined symbol: DrawGradientImage
    /usr/lib/libWand.so.9: undefined symbol: AcquireDrawInfo
    /usr/lib/libWand.so.9: undefined symbol: AcquireOneMagickPixel
    /usr/lib/libWand.so.9: undefined symbol: FormatMagickTime
    /usr/lib/libWand.so.9: undefined symbol: FormatMagickSize
    /usr/lib/libWand.so.9: undefined symbol: QueryMagickColorname
    /usr/lib/libWand.so.9: undefined symbol: ClearMagickException
    >>> MagickWandGenesis()
    >>> wand = NewMagickWand()
    >>> MagickReadImage(wand,�sample.jpg�)
    File “”, line 1
    MagickReadImage(wand,�sample.jpg�)
    ^
    SyntaxError: invalid syntax
    >>> MagickReadImage(wand,”sample.jpg”)

    >>> MagickScaleImage(wand,200,200)

    >>> MagickWriteImage(wand,”out.png”)

    >>> MagickReadImage(wand,”Badge_Sample_3.pdf”)

    >>>
    carl@asus17:~/temp$

    out.png looks good.

    hoping to convert the pdf to a png. after about 5 secconds, it dropped me out of python. looks like I have a memory problem:

    carl@asus17:~/temp$ free -m
    total used free shared buffers cached
    Mem: 1011 955 55 0 109 388
    -/+ buffers/cache: 457 553
    Swap: 964 0 964

    I’ll reboot and see if it is any better.

    Comment by CarlFK — December 27, 2007 @ 19:15

  2. from PythonMagickWand import *
    MagickWandGenesis()
    wand = NewMagickWand()
    MagickReadImage(wand,”Badge_Sample_3.pdf”)
    MagickWriteImage(wand,”badge.png”)

    it works!

    carl@asus17:~/temp$ free -m
    total used free shared buffers cached
    Mem: 1011 513 497 0 26 263
    -/+ buffers/cache: 223 787
    Swap: 964 0 964

    too bad it takes 8 seconds, wich may be too long for what I need. but I may be able to make a smaller pdf. (not your problem)

    Comment by CarlFK — December 27, 2007 @ 20:13

  3. woo! my quest is over! a more realistic test of the kind of pdf I want to use resulted in .4 seconds on my p4-1.7ghz.

    What a nice christmas pressent.

    Thanks again.

    Comment by CarlFK — December 27, 2007 @ 21:19

  4. Having trouble:

    Python 2.5.1 (r251:54863, Jan 3 2008, 23:31:31)
    [GCC 3.4.6 20060404 (Red Hat 3.4.6-9)] on linux2
    Type “help”, “copyright”, “credits” or “license” for more information.
    >>> import ctypes
    >>> _magick = ctypes.CDLL(”/usr/lib/libWand.so.6″)
    >>> from PythonMagickWand import *
    Traceback (most recent call last):
    File “”, line 1, in
    File “/home/webadmin/PythonMagickWand.py”, line 79, in
    _magick.MagickWandGenesis()
    File “/var/tmp/python2.5-2.5.1-root/usr/lib/python2.5/ctypes/__init__.py”, line 353, in __getattr__
    File “/var/tmp/python2.5-2.5.1-root/usr/lib/python2.5/ctypes/__init__.py”, line 358, in __getitem__
    AttributeError: /usr/lib/libWand.so.6: undefined symbol: MagickWandGenesis
    >>>

    Any suggestions?

    Ramon

    Comment by Ramon — January 5, 2008 @ 7:34

  5. Hello.
    Are the Pixel Iterator Methods implemented?

    Comment by kurt — January 11, 2008 @ 16:38

  6. See http://www.procoders.net/?p=67 for more informations about PythonMagickWand

    Comment by Achim — January 13, 2008 @ 15:38

  7. [...] Imagemagick i MagickWand [...]

    Pingback by Pícsels, bytes i alguna cosa més … » Blog Archive » Llibreries per imatges, per python — January 14, 2008 @ 17:34

  8. koopa freelive # python PythonMagickWand.py
    Traceback (most recent call last):
    File “PythonMagickWand.py”, line 76, in
    _magick = ctypes.CDLL(’/usr/lib/libWand.so.10′)
    File “/usr/lib/python2.5/ctypes/__init__.py”, line 340, in __init__
    self._handle = _dlopen(self._name, mode)
    OSError: /usr/lib/libWand.so.10: undefined symbol: ClutImageChannel

    Use ImageMagick6.3.5 / and Gentoo and PythoMagick0.7 installed

    What is happend?

    Comment by Joao Rego — February 12, 2008 @ 2:44

  9. Thanks for good work for python and magickwand !!

    I tried PythonMagickWand.py in Windows XP and Debian Linux.
    It works fine with following Library path
    * WinXP : r“C:\Program Files\ImageMagick-6.3.9-Q16\CORE_RL_wand_.dll�
    *Debian Linux : “/usr/lib/libWand.so.9″

    I also make patch for try correct library path for each(mac, win, linux) os.
    go to following link, get “os_free.zip” and apply it to “PythonMagickWand.py”

    http://web.suapapa.net:8080/wordpress/?p=122

    Comment by suapapa — March 17, 2008 @ 11:19

  10. Hey, are you going to develop this binding set further? It would be kind of neat.

    Comment by qubodup — April 6, 2008 @ 5:18

  11. It works well for me, keep up this great work!

    Now i just have to fight with the non-pythonic MagickWand API :)

    Comment by Werner Hartnagel — May 21, 2008 @ 12:04

  12. It’s cool, I had to use the patch to make it work in windows. + replaced all the exception outputs with pass. Would be nice to have a more pythonic wrapper :)

    Comment by Stu — November 10, 2008 @ 12:17

  13. Some more examples would be really cool - like how to get image dimensions

    Comment by Stu — November 10, 2008 @ 19:35

  14. [...] page. it may not even be saved to the DB yet. the new ImageMagick bindings should do what I need: http://www.procoders.net/?p=39 Carl [...]

    Pingback by convert pdf to png - Page 2 | keyongtech — January 22, 2009 @ 5:16

  15. [...] support for icon files and stumpled upon my old friend ImageMagick. I’ve found that there are Python bindings for the MagickWand interface (the C API). Yet, those bindings are incomplete, ugly and not actively maintained. I’ve found [...]

    Pingback by Benjamin Schweizer. Python-MagickWand or How to Work With Icons. — June 18, 2009 @ 8:47

  16. There’s an alternate implementation of the MagickWand interface, see http://benjamin-schweizer.de/python-magickwand-or-how-to-work-with-icons.html

    Comment by Benjamin Schweizer — June 18, 2009 @ 8:55

  17. PixelSetColor function messed. You can add binding like this:
    —-

    # PixelSetColor
    try:
    _magick.PixelSetColor.restype = None
    _magick.PixelSetColor.argtypes = (PixelWand, ctypes.POINTER(ctypes.c_char))
    except AttributeError,e:
    print e
    else:
    PixelSetColor = _magick.PixelSetColor

    —-

    Comment by Maxim Polshcha — June 23, 2009 @ 11:24

  18. [...] PythonmagickWand, http://www.procoders.net/?p=39 (’Due to the still existing demand for python bindings for ImageMagick I have created PythonMagickWand which is based on ctypes‘) [...]

    Pingback by Traitement d’images avec python: python-magic, pyexiv2, PIL, ReportLab, Motmot, Pythonmagick, magickpy « Le blog de Patrick Vergain — August 21, 2009 @ 15:35

  19. I’ve done some changes on animation and image sequences support. If somebody needs mail me maxp_at_sterch.net

    Comment by Maxim Polscha — September 8, 2009 @ 15:51

RSS feed for comments on this post. TrackBack URI

Leave a comment

Powered by WordPress | Theme by Roy Tanck

Stoppt die Vorratsdatenspeicherung! Jetzt klicken & handeln!Willst du auch bei der Aktion teilnehmen? Hier findest du alle relevanten Infos und Materialien: