It’s been a slow start to the new year; but, here is a new package called trivial-freeimage. It wraps most of the FreeImage Library. I got this to work on Windows with CFFI 0.9.2 by building the FreeImage dll without stdcall linking. It was a simple edit to the header file. Anyway, here is a simple example that has functions to find the top and bottom of an image of text from a tiff-g4 scanned page:
(require 'asdf)
(require 'cffi)
(load "trivial-freeimage.lisp")
(in-package :trivial-freeimage)
(initialize 0)
;load a tiff-g4 image and get it's height and width
;width is divided by 8 due to 1 pixel per bit in tiff-g4 format
(defvar dib (load-image tiff "24.tif" 0))
(defvar height (get-height dib))
(defvar width (/ (get-width dib) 8))
;as soon as we find a black pixel notify
(defun row-has-black? (row)
(loop for i from 0 upto (- width 1) do
(if (> (mem-aref row :uchar i) 0)
(return t))))
;find the top of the frame of text
(defun find-top (dib)
(loop for row from (- height 1) downto 0 do
(if (row-has-black? (get-scan-line dib row))
(return (- height row)))))
;find the bottom of the frame
(defun find-bottom (dib)
(loop for row from 0 upto height do
(if (row-has-black? (get-scan-line dib row))
(return (- height row)))))
;always unload your dib's or you will never free the memory
(unload-image dib)
(de-initialize)
Also, note that FreeImage stores DIB’s with the origin being in the bottom left.
One other example– to convert a tiff file to png:
(in-package :trivial-freeimage)
(initialize 0)
(defvar dib (load-image tiff "image.tif" 0))
(save-image png dib "image.png" 0)
(unload-image dib)
(unload-image dib2)
(de-initialize)
I will be posting more examples while I work on the documentation of how to use the wrapping. Also, I will continue to add more of FreeImage’s API to the wrapping. I plan on adding a higher package for image editing that will make use of trivial-freeimage.
1 response so far ↓
Zach // January 15, 2007 at 2:03 am
Here are a few thoughts:
- Name special variables with stars around the name. Otherwise you can unintentionally bind variables dynamically when you meant to bind them lexically
- Export symbols from your library package, then make new packages that either :use the library package, or just use qualified symbols. Don’t make applications that are in the package of the library
- Indent conventionally. Your DEFUN and IF are way over to the right.
- Use conventional names.
- consider making a WITH-DIB macro to manage loading and releasing resources
- Don’t use LOAD in source files to get your system into shape, use a system definition
Hope this helps…
Leave a Comment