;;;
;;; | png-to-text.lisp
;;; | What it says on the tin
;;; +------------------------
;;;
;;; ./png-to-text.lisp <FILE_NAME> <WIDTH> <HEIGHT>
;;;
;;; Author: Andres V.
;;; License: GPL V3
;;; Anyone and everyone is allowed to use and change this,
;;; do whatever you want.
;;; Notes: This only supports PNG files.
(ql:quickload "png")
(defun flatten (l)
(cond ((null l) nil)
((atom l) (list l))
(t (loop for a in l appending (flatten a)))))
(defun average (l) (/ (apply #'+ l) (list-length l)))
(defun normalize-pixel (image x y)
"Gray-scale-ifies the pixel to be a single value"
(let ((values (loop for c from 0 to (1- (png:image-channels image))
:collect (if (and (< x (png:image-width image))
(< y (png:image-height image)))
(aref image y x c)
0))))
(average values)))
(defun average-brightness (image x y w h)
"Returns the average brightness in a scale from 0 to 1 of the pixel group"
(let ((values (flatten (loop for i from x to (1- (+ x w))
:collect
(loop for j from y to (1-(+ y h))
:collect (normalize-pixel image i j))))))
(/ (average values) 256)))
(defun selector (number selectors)
"Takes a number to compare to and a selectors list composed of a number
to compare to and a return value"
(second (find-if (lambda (x) (>= number (first x))) selectors)))
(defun blockify-image (image w h)
(let* ((sw (floor (png:image-width image) w)) (sh (floor (png:image-height image) h)))
(loop for i from 0 to (1- w)
:collect
(loop for j from 0 to (1- h) :collect
(select-block (average-brightness image (* i sw) (* j sh) sw sh))))))