I've been tinkering with ROS using ROS2Djs over ROS bridge and their excellent simulation environment. Along the way, I learnt that ROS saves its maps as a PGM file. An excellent idea, if you think about it. It is textual and lends itself well to algorithmic processing. But I am not aware of a way to display a PGM file on the browser like the image that it is.
I was initially experimenting with Python since ROS has excellent support for python. Then I tried to repeat my experiments using Common Lisp. ROS1 has pretty good support for CL, if not at Python levels. I used the excellent PIL API in python to get the conversion going. The code was as simple as this:
# python2. yikes!
buffer = cStringIO.StringIO()
pgm = Image.open(filename)
pgm.save(buffer, format="png")
I could have tried the same thing using Common Lisp libraries for image magick. But then, I wanted to give myself a little challenge. There is an excellent png library for common lisp and another excellent netpbm library for common lisp too. So I decided to write a simple glue code combining these two libraries with doing my bidding. Here is what that glue looks like:
;; damn, there is still no support for common lisp syntax? I should
;; move away I guess
(defun read-pgm (pgm-filename)
"reads a pgm file and returns the data array"
(netpbm:read-from-file pgm-filename))
(defun convert-to-1d-array (2d-data)
"read-pgm returns a 2d simple-array. We need a 1d vector for png generation."
(let* ((rows (array-dimension 2d-data 0))
(cols (array-dimension 2d-data 1))
(1d-data '()))
(dotimes (r rows)
(dotimes (c cols)
(setf 1d-data (append 1d-data (list (aref 2d-data r c))))))
(make-array (* rows cols) :initial-contents 1d-data :element-type '(unsigned-byte 8))))
(defun generate-png (pgm-filename)
(let* ((pgm-data (read-pgm pgm-filename))
(w (array-dimension pgm-data 0))
(h (array-dimension pgm-data 1))
(image-data (convert-to-1d-array pgm-data)))
(type-of image-data)
(make-instance 'zpng:png
:color-type :grayscale
:width w
:height h
:image-data image-data)))
(defun write-pngfile (pgm-filename png-filename)
"reads in a pgm file and writes out a png image"
(let ((png-data (generate-png pgm-filename)))
(format t "generating png file.")
(zpng:write-png png-data png-filename)))
I hope you find that helpful. I am considering making a package with these utilities: pgm -> png, jpg; files and base64 strings and releasing it into the wild.