January 14, 2007

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)

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)

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.


One Response to “trivial-freeimage”

  1. Zach Says:

    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 Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: