Now that we have the ImageMagick bindings set up, we will try to do something ‘useful’ with what we have done.

I wanted to do something similar to what we find here that matches the C source code that we find here

so, we are combining the images:

Src Dest Mask

to end up with an image that looks like this:

Finished Image

Here is the lisp source:

; load imagemagick bindings
(use-interface-dir :imagemagick)

; load the shared library
(open-shared-library "libMagickWand.so")

; use with-cstrs to convert lisp strings to c style strings that
; we can pass to functions
(with-cstrs ((water "/home/kelly/blog/tile_water.jpg")
	     (aqua "/home/kelly/blog/tile_aqua.jpg")
	     (moon "/home/kelly/blog/moon_mask.gif")
	     (output "/home/kelly/blog/clip_out.jpg"))
  ; use #_ as a macro to reference functions
  (setf dest (#_NewMagickWand))
  (setf mask (#_NewMagickWand))
  (setf src (#_NewMagickWand))

  (#_MagickReadImage dest aqua)
  (#_MagickReadImage mask moon)
  ; use #$ as a macro to reference constants
  (#_MagickNegateImage mask #$MagickFalse)

  (#_MagickReadImage src water)
  ; use #> as a macro to reference structures
  ; and pref to dreference pointers
  (setf (ccl:pref dest #>MagickWand.images.mask) (ccl:pref mask #>MagickWand.images))

  (#_MagickCompositeImage dest src #$OverCompositeOp 0 0)
  ; null pointer with the %null-ptr macro
  (setf (ccl:pref dest #>MagickWand.images.mask) (ccl:%null-ptr))

  (#_MagickWriteImage dest output)

  (#_DestroyMagickWand src)
  (#_DestroyMagickWand dest)
  (#_DestroyMagickWand mask))


As you can tell, we pretty much followed the C source code exactly, using the macros that Clozure provides (documentation)
If we wanted to do other things, we would use the ImageMagick API documentation here

The next post will show how to allocate memory and interface with a function that has a little more complicated call where we pass in a pointer of a data structure that we created in lisp and get back a pointer to memory.

Advertisement