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.