Skip to content

Instantly share code, notes, and snippets.

@rm-hull
Last active December 18, 2015 05:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rm-hull/5736733 to your computer and use it in GitHub Desktop.
Save rm-hull/5736733 to your computer and use it in GitHub Desktop.
A SIRD (Single Image Random Dot) diagram, a.k.a. 'Magic Eye' or autostereogram is a single-image stereogram (SIS), designed to create the visual illusion of a three-dimensional (3D) scene within the human brain from an external two-dimensional image. In order to perceive 3D shapes in these autostereograms, one must overcome the normally automati…
(ns autostereogram.demo
(:use [monet.canvas :only [draw-image]]
[enchilada :only [canvas ctx proxy-request]]
[jayq.core :only [show]]
[jayq.util :only [log]]))
(def greens
(map #(vector 0x30 % 0x30 0xFF) (range 0xCF)))
(defn random-data [w h colors]
(let [v (vec colors)
sz (count v)
rnd-color #(get v (rand-int sz))]
{ :width w
:height h
:data (vec (repeatedly h
#(vec (repeatedly w rnd-color))))}))
(defn depthmap-url
([] (depthmap-url (rand-int 10)))
([n] (str "https://raw.github.com/rm-hull/depth-maps/master/" n ".jpg")))
(defn load-image! [url & [callback-fn]]
(let [img (js/Image.)]
(println "Loading image: " url)
(when callback-fn
(set! (.-onload img) (fn [] (callback-fn img))))
(set! (.-crossOrigin img) "anonymous")
(set! (.-src img) (proxy-request url)))
img)
(defn offset [[x y] w]
(* (+ (* y w) x) 4))
(defn get-point [arr width co-ords]
(let [offset (offset co-ords width)]
(map #(aget arr %) (range offset (+ offset 4)))))
(defn set-point! [arr width co-ords data]
(loop [idx (offset co-ords width)
data data]
(when (seq data)
(aset arr idx (first data))
(recur (inc idx) (rest data)))))
(defn depth
"Input data assumed to be [r g b a], normalize to range 0..31 from green byte"
[data]
(quot (second data) 8))
(defn generate-sird [img rand-data]
(let [width (.-width img)
height (.-height img)]
(draw-image ctx img { :x 0 :y 0 :w width :h height })
(let [depth-map (. ctx (getImageData 0 0 width height))
data (.-data depth-map)
rand-w (:width rand-data)
set-pt! (partial set-point! data width)
split-point (- width 1 rand-w)]
(doseq [y (range height)
:let [rand-row (get (:data rand-data) (mod y (:height rand-data)))]
x (range (dec width) -1 -1)
:let [depth (depth (get-point data width [x y]))]]
(set-pt!
[x y]
(if (> x split-point)
(get rand-row (mod (- x depth) rand-w))
(get-point data width [(- (+ x rand-w) depth) y]))))
(. ctx (putImageData depth-map 0 0)))))
(show canvas)
(load-image!
(depthmap-url)
#(generate-sird % (random-data 100 100 greens)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment