Mercurial > lasercutter
comparison src/clojureDemo/Xuggle.clj @ 1:6d9bdaf919f7
added clojureDemo source
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 20 Aug 2010 00:32:44 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:163bf9b2fd13 | 1:6d9bdaf919f7 |
---|---|
1 (ns clojureDemo.Xuggle) | |
2 | |
3 (import '(ij ImagePlus IJ)) | |
4 (import '(java.awt Rectangle Robot Toolkit) ) | |
5 (import '(java.awt.image BufferedImage) ) | |
6 (import '(java.awt Graphics2D Panel)) | |
7 (import '(java.io File) ) | |
8 (import '(javax.imageio ImageIO) ) | |
9 (import '(com.xuggle.mediatool ToolFactory)) | |
10 (import '(com.xuggle.mediatool IMediaDebugListener IMediaDebugListener$Event)) | |
11 (import '(com.xuggle.mediatool MediaToolAdapter MediaListenerAdapter)) | |
12 (import '(com.xuggle.xuggler IContainer IContainer$Type IPacket)) | |
13 (import '(javax.swing JFrame)) | |
14 (import '(com.xuggle.mediatool IMediaWriter)) | |
15 (import '(org.apache.commons.io FileUtils)) | |
16 (import '(javax.imageio.stream FileImageOutputStream)) | |
17 (import '(javax.imageio ImageWriteParam IIOImage)) | |
18 (import '(com.xuggle.xuggler IRational)) | |
19 (import '(java.util.concurrent TimeUnit)) | |
20 (import '(com.xuggle.xuggler ICodec)) | |
21 | |
22 (use 'clojureDemo.Defines) | |
23 ;(use '[clojureDemo.OpenCv :only (video-data)]) | |
24 | |
25 | |
26 | |
27 (import '(java.io File)) | |
28 (import '(org.apache.commons.io FileUtils)) | |
29 (import '(javax.imageio ImageIO) ) | |
30 | |
31 (import '(ij.plugin PlugIn)) | |
32 (import '(ij ImagePlus IJ)) | |
33 | |
34 | |
35 (use 'clojure.contrib.repl-utils) | |
36 (use ['clojureDemo.Defines | |
37 :only '( | |
38 lian look getto human0 blow base app0 app1 app2 app3 app4 app5 | |
39 bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6 | |
40 collide0 collide1 collide2 collide3 collide4 | |
41 give0 give1 give2 give3 give4 target default)]) | |
42 | |
43 | |
44 ;(def hamster (ImagePlus. "lklk" (first (video-seq look)))) | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 (defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil)))) | |
51 | |
52 | |
53 (defmulti display "Creates a JFrame and displays a buffered image" class) | |
54 | |
55 (defmethod display | |
56 BufferedImage [image] | |
57 (let [panel (makePanel image) | |
58 frame (JFrame. "Oh Yeah!")] | |
59 (.add frame panel) | |
60 (.pack frame) | |
61 (.setVisible frame true ) | |
62 (.setSize frame(.getWidth image) (.getHeight image)))) | |
63 | |
64 (defmethod display | |
65 ImagePlus [image] | |
66 (display (.getBufferedImage image))) | |
67 | |
68 | |
69 | |
70 | |
71 (defn flash | |
72 [image] | |
73 | |
74 (.start (Thread. (fn [] | |
75 (do | |
76 (.show image) | |
77 (.updateAndRepaintWindow image) | |
78 (Thread/sleep 4000) | |
79 (.hide image)))))) | |
80 | |
81 | |
82 (defn readerRecurse | |
83 "calls .readPacket until there's nothing left to do" | |
84 [reader] | |
85 (if (not (nil? (.readPacket reader))) ; here .readPacket actually does the processing as a side-effect. | |
86 nil ; it returns null when it has MORE to process, and signals an error when done... | |
87 (recur reader))) | |
88 | |
89 | |
90 (def *cache-directory* (File. "/home/r/Desktop/vision-cache")) | |
91 (def *ext* "jpg") | |
92 | |
93 | |
94 | |
95 | |
96 (defn writeJpg | |
97 "WTF is this shit?!" | |
98 [image target quality] | |
99 (let [jpgWriter (.next (ImageIO/getImageWritersByFormatName *ext*))] | |
100 (doto (.getDefaultWriteParam jpgWriter) | |
101 (.setCompressionMode ImageWriteParam/MODE_EXPLICIT) | |
102 (.setCompressionQuality quality)) | |
103 (doto jpgWriter | |
104 (.setOutput (FileImageOutputStream. target)) | |
105 (.write (IIOImage. image nil nil)) | |
106 (.dispose)))) | |
107 | |
108 | |
109 | |
110 (defn cache-path | |
111 [video] | |
112 (File. *cache-directory* (.getName video))) | |
113 | |
114 (defn video-frame-path | |
115 [video n] | |
116 (File. (cache-path video) (str n "." *ext*))) | |
117 | |
118 | |
119 (defn already-cached | |
120 "this is the simplest and most retarded way to do it" | |
121 [video] | |
122 (.exists (cache-path video))) | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 (defn make-incrementer [start increment] (let [a (ref (- start increment))] (fn [] (dosync (ref-set a (+ @a increment)))))) | |
130 | |
131 (defn make-frame-writer | |
132 [video] | |
133 (let [incrementer (make-incrementer 0 1)] | |
134 (proxy [MediaListenerAdapter] [] | |
135 | |
136 (onVideoPicture | |
137 [event] | |
138 ;(println (.getImage event)) | |
139 ;(println (File. (cache-path video) (str (incrementer) "." *ext* ) )) | |
140 | |
141 (let [target (File. (cache-path video) (str (incrementer) "." *ext* ))] | |
142 (if (= *ext* "jpg") | |
143 (writeJpg (.getImage event) target 1) | |
144 (ImageIO/write (.getImage event) *ext* target ))))))) | |
145 | |
146 | |
147 | |
148 (defn cache | |
149 "caching of frames without opencv" | |
150 [video] | |
151 | |
152 (if (already-cached video) | |
153 nil | |
154 (time | |
155 (let [reader (ToolFactory/makeReader (str video))] | |
156 (println "slow cache!") | |
157 (FileUtils/forceMkdir (cache-path video)) | |
158 (doto reader | |
159 (.setBufferedImageTypeToGenerate BufferedImage/TYPE_3BYTE_BGR) | |
160 (.addListener (make-frame-writer video)) | |
161 (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA])))) | |
162 (readerRecurse reader))))) | |
163 | |
164 | |
165 (defn video-data | |
166 "get video data without opencv" | |
167 [video] (cache video) | |
168 | |
169 | |
170 {:length (- (count (file-seq (cache-path video))) 1) | |
171 :width (.getWidth (ImagePlus. (str (video-frame-path video 0)))) | |
172 :height (.getHeight (ImagePlus. (str (video-frame-path video 0)))) | |
173 :fps 30}) ; yeah --- I'll figure this out later. | |
174 (def video-data (memoize video-data)) | |
175 | |
176 | |
177 | |
178 (defn convert | |
179 "takes video and converts it to a new type of video" | |
180 [videoInput videoOutput] | |
181 (let [reader (ToolFactory/makeReader (str videoInput))] | |
182 (doto reader | |
183 (.addListener (ToolFactory/makeWriter (str videoOutput) reader)) | |
184 (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA])))) | |
185 (readerRecurse reader))) | |
186 | |
187 | |
188 (import '(com.xuggle.xuggler.video ConverterFactory)) | |
189 | |
190 | |
191 (defn trans-save | |
192 "this is a transitive way to save a stream to an avi file. | |
193 It uses meta data to determine what fps to use to encode." | |
194 [destination video-seq] | |
195 (let [data (meta video-seq) | |
196 writer (ToolFactory/makeWriter (str destination)) | |
197 incrementer (make-incrementer 0 (/ 1 30))] | |
198 (.addVideoStream writer 0 0 (ICodec/findEncodingCodecByName "mpeg4") | |
199 (IRational/make (double (:fps data))) | |
200 (int (:width data)) (int (:height data))) | |
201 (dorun (map #(.encodeVideo writer 0 | |
202 (ConverterFactory/convertToType (.getBufferedImage %) BufferedImage/TYPE_3BYTE_BGR) | |
203 (long (* 1000000000 (incrementer))) TimeUnit/NANOSECONDS) video-seq)) | |
204 (.close writer)) | |
205 video-seq) | |
206 | |
207 | |
208 (defn video-seq | |
209 "let's use ImagePlus stuff!" | |
210 ([video] (cache video) | |
211 (with-meta (map #(ImagePlus. (str (video-frame-path video %))) (range (:length (video-data video))) ) (video-data video)))) | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 (comment | |
219 (do (use :reload-all 'clojureDemo.Xuggle) (in-ns 'clojureDemo.Xuggle)) | |
220 ) | |
221 |