;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Pixelate video into 32*32 grid
;;
;; Create a pixellated image and transfer the pixel colours
;; to an identical number of vector paths. Then draw the vector
;; paths over the top of the original image.
;;
;; Move the vector paths by a small amount each animation frame.
;;
;; Note that the vector paths and the back ground image are
;; opposites.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(gfx:start-live-video)
(define row-length 32) ; number of squares to animate
(define nodes (* row-length row-length))
(define size 20) ; square size
; set up graphics including vectors for paths, points, colours, styes etc.
(define canvas (gfx:make-canvas (* size row-length) (* size row-length)))
(gfx:clear-canvas (now) canvas '(0 0 0 1)) ; black background
; setup paths at random coordinates between 100,100 and 200,200
(define paths (make-vector-with-proc nodes
(lambda (i)
(gfx:make-square (* size (floor (/ (- nodes i 1) row-length)))
(* size (fmod (- nodes i 1) row-length))
size))))
;; styles
(define styles (make-vector nodes *gfx:fill-path*))
;; strokes to 0
(define strokes (make-vector nodes 0))
;; widths to 0
(define widths (make-vector nodes 1))
;; x,y coordinates to retrieve pixels from image
(define idxs (make-vector (* 1024 2)))
;; setup x,y coordinates
(dotimes (i 1024)
(let ((k (* i 2)))
(vector-set! idxs k (real->integer (/ i row-length)))
(vector-set! idxs (+ k 1) (fmod i row-length))))
;; vectors for holding random x and y coordinates
(define randx (make-vector 1024 0))
(define randy (make-vector 1024 0))
;; animate movie
;;
;; 1) get image from camera
;; 2) pixellate image (i.e. compress from full size down to 32*32)
;; 3) choose random numbers between -0.5 ... 0.5 for amount to move paths by (x and y)
;; 4) move paths by x and y amounts
;; 5) draw camera image onto the background (scaling from 640*480 to 640*640)
;; 6) draw paths onto the background image (over the top of the camera image)
;; 7) draw background to the canvas
;;
;; Try replacing the second image2image expression with (clear-image background-image '(0 0 0 1))
(define animate
(lambda (time pixel-image background-image)
(let ((camera-image (gfx:convert-image (gfx:get-live-frame))))
(gfx:image2image camera-image pixel-image 1.0 (list 0 0 row-length row-length) '(0 0 640 480))
(math:vector-rand randx) ;; generate 1024 random numbers
(math:vector-rand randy) ;; generate 1024 random numbers
(math:vector- randx .5) ;; change range from 0 ... 1 to -0.5 ... 0.5
(math:vector- randy .5) ;; change range from 0 ... 1 to -0.5 ... 0.5
(gfx:move-group time paths randx randy) ;; move 1024 paths by randx randy
(gfx:image2image camera-image background-image 1.0
(list 0 0 (* row-length size) (* row-length size)) '(0 0 640 480)) ;; draw camera image onto background
(gfx:group2image background-image paths strokes
(gfx:get-image-pixels pixel-image idxs) widths styles) ;; draw all paths onto background
(gfx:draw-image time canvas background-image 1) ;; draw background to canvas
(callback (+ time 3000) 'animate (+ time 5000) pixel-image background-image))))
;; call animage and create background and pixel images
;; to be resused (i.e. we don't want to re-create them in each animation frame)
;;
(animate (now)
(gfx:make-image row-length row-length)
(gfx:make-image (* row-length size) (* row-length size)))