ImageMagick (www.imagemagick.org) is a suite of tools allowing you to create, edit, and compose bitmap images. It provides powerful command-line tools to this effect, but also provides a number of APIs to make the same features available programmatically.
Binary releases of the ImageMagick suite (including libraries) can be downloaded here:
In the following example, we make use of the MagickWand API to the ImageMagick library to dynamically generate a thumbnail index for an image repository on a web server.
In demo/US_State_Flags are png files of the 50 states retrieved from the following site:
The images here vary in size, but none are smaller than roughly 225x225. The example below publishes the directory containing these images. However, in place of an index.html file that shows the contents of this directory, it will dynamically generate an index of the contents of the directory, creating a small thumbnail of each file.
This will compile and load the demo. To run it you'll be starting a server on the local machine via the function start-server. This function takes an optional argument indicating the port on which the server listens. It default to 8080. If that is acceptable, you can start the server by evaluating
Else, you should specify a port. for example, to start a server on port 9000, evaluate:
The server should now be up and running.
(setq *thumb-dims* "50x50")and then refresh the page with the thumbnail view. You should see the size of the thumbnails in the index change accordingly. Here is a portion of the webpage with the smaller thumbnails:
The full code for this demo can be found in demo/demo-thumb.cl and the files that it loads. Below, we look at a few details as relates to the ImageMagick API.
The code for setting up the server and starting it can be found in demo/demo-thumb.cl. The main workhorse in this file is the function publish-thumbnail.
(defun publish-thumbnails () (ensure-directories-exist *thumb-tmp*) (dolist (i (directory *flag-dir*)) (let ((name (file-namestring i)) (in-file (enough-namestring i)) (out-file (sys:make-temp-file-name "thumb" *thumb-tmp*)) (mime-type (net.aserve::lookup-mime-type i))) (publish :path (format nil "/thumbs/~a" name) :content-type mime-type :format :binary :function #'(lambda (req ent) (MagickWand::xform-image in-file *thumb-dims* out-file) (with-http-response (req ent) (with-http-body (req ent) (with-open-file (thumb out-file :direction :input) (let (byte) (while (setf byte (read-byte thumb nil nil)) (write-byte byte *html-stream*)))) (delete-file out-file))))))))
For each file in *thumb-dir*, an entity is published which calls MagickWand:xform-image to resize an existing image while maintaining aspect ratio, and write it to a temp file, and then emit it in response to an http request. Lastly, for both tidiness and to ensure that the thumbnail is generated each time, the temp file is removed.
The function MagickWand::xform-image is a helper routine defined in demo/demo-resize.cl that makes use of the MagickWand binding to have ImageMagick do the work of creating and writing out the thumbnails.
(defun xform-image (in-file new-dims out-file) (let ((wand (NewMagickWand)) images-modified) (when (= (MagickReadImage wand in-file) MagickFalse) (error "unable to read image file ~s." in-file)) (MagickResetIterator wand) (let (xforms) (while (/= (MagickNextImage wand) MagickFalse) (push (MagickTransformImage wand "0x0" new-dims) xforms) (setf images-modified t)) (if* images-modified then (when (= (MagickWriteImages (first xforms) out-file MagickTrue) MagickFalse) (error "unable to write to file ~s." out-file)) else (error "No images found in input file ~s." in-file))) images-modified))
For more information on what the MagickWand API routines do, you are referred to the "MagickWand API" (www.imagemagick.org/script/magick-wand.php)
In the downloaded distribution, the files MagickWand.cl found in the architecture specific subdirectories of windows/ and linux86/ were generated using the Makefile found in this distribution by running an up-to-date SWIG on MagickWand.i. If you wish to generate this interface on additional platforms, you can use this interface and the accompanying Makefile as a reference. See the README file in the downloaded distribution for more details.
If you have any questions about the interface or suggestions, please email us at firstname.lastname@example.org.
|Copyright © 2018 Franz Inc., All Rights Reserved | Privacy Statement|