Uses 1482K of libraries. Click here for Pure Java version (13406L/67K).
1 | !7 |
2 | |
3 | !include early #1033506 // Compact Module Include Gazelle V |
4 | |
5 | module GazelleScreenCam { |
6 | !include early #1025212 // +Enabled without visualization |
7 | |
8 | int screenNr; |
9 | int pixelRows = 128, colors = 8; |
10 | S script, testScreenScript; |
11 | bool animate = true; |
12 | bool horizontalLayout; // flat layout |
13 | |
14 | transient ImageSurface isPosterized, isRegions, isTestScreen; |
15 | transient new ScreenCamStream images; |
16 | transient new BWIntegralImageStream integralImages; |
17 | transient new SourceTriggeredStream<BWImage> scaledAndPosterizedImages; |
18 | transient new DoubleFPSCounter fpsCounter; |
19 | transient int fps; |
20 | transient ScreenSelectorRadioButtons screenSelector; |
21 | transient new RollingAverage remainingMSPerFrame; |
22 | transient int remainingMS; |
23 | |
24 | transient new FunctionTimings<S> functionTimings; |
25 | |
26 | transient ReliableSingleThread rstRunScript = dm_rst(me(), r _runScript); |
27 | |
28 | transient JGazelleVScriptRunner scriptRunner; |
29 | transient JGazelleVScriptRunner testScreenScriptRunner; |
30 | |
31 | transient Animation animation; |
32 | |
33 | transient BWImage_FastRegions mainScreenRegions; |
34 | transient ImageSurface_HighlightRegion regionHighlighter; |
35 | |
36 | transient UIURLSystem uiURLs; |
37 | S uiURL; |
38 | |
39 | start { |
40 | dm_onFieldChange horizontalLayout( |
41 | //r dm_revisualize // deh buggy |
42 | r dm_reload |
43 | ); |
44 | |
45 | uiURLs = new UIURLSystem(me(), dm_fieldLiveValue uiURL()); |
46 | |
47 | scriptRunner = new JGazelleVScriptRunner(dm_fieldLiveValue script(me())); |
48 | testScreenScriptRunner = new JGazelleVScriptRunner(dm_fieldLiveValue testScreenScript(me())); |
49 | |
50 | images.directlyFeedInto(integralImages); |
51 | |
52 | integralImages.onNewElement(ii -> |
53 | scaledAndPosterizedImages.newElement( |
54 | posterizeBWImage_withMeta(colors, |
55 | scaledBWImageFromBWIntegralImage_withMeta_height(pixelRows, ii)))); |
56 | |
57 | integralImages.onNewElement(r { |
58 | if (shouldRunScript()) rstRunScript.go(); |
59 | }); |
60 | |
61 | scaledAndPosterizedImages.onNewElement(img -> { |
62 | fpsCounter.inc(); |
63 | setField(fps := iround(fpsCounter!)); |
64 | isPosterized?.setImage_thisThread(img); |
65 | floodFill(img); |
66 | }); |
67 | |
68 | // 20 Hz is enough for everyone |
69 | dm_doEvery(1000/20, r { |
70 | if (enabled) { |
71 | screenSelector?.updateScreenCount(); |
72 | Timestamp deadline = tsNowPlusMS(1000/20); |
73 | images.useScreen(screenNr); |
74 | images.step(); |
75 | long remaining = deadline.minus(tsNow()); |
76 | remainingMSPerFrame.add(remaining); |
77 | setField(remainingMS := iround(remainingMSPerFrame!)); |
78 | } |
79 | }); |
80 | } |
81 | |
82 | ImageSurface stdImageSurface() { |
83 | ret pixelatedImageSurface().setAutoZoomToDisplay(true).repaintInThread(false); |
84 | } |
85 | |
86 | visualize { |
87 | screenSelector = new ScreenSelectorRadioButtons(dm_fieldLiveValue screenNr()); |
88 | screenSelector.compactLayout(true); |
89 | screenSelector.hideIfOnlyOne(true); |
90 | screenSelector.screenLabel(""); |
91 | isPosterized = stdImageSurface(); |
92 | regionHighlighter = new ImageSurface_HighlightRegion(isPosterized); |
93 | regionHighlighter.regionPainter(new RegionFillPainter); |
94 | |
95 | isRegions = stdImageSurface(); |
96 | isTestScreen = stdImageSurface(); |
97 | |
98 | // when test screen is visible, do the animation |
99 | awtEvery(isTestScreen, 1000/20, r stepAnimation); |
100 | |
101 | JTextArea taTimings = jTextArea_noUndo(); |
102 | awtEveryAndNow(taTimings, .5, r { |
103 | setText(taTimings, renderFunctionTimings()) |
104 | }); |
105 | |
106 | var jSpeedInfo = dm_transientCalculatedToolTip speedInfo_long(rightAlignLabel(dm_transientCalculatedLabel speedInfo())); |
107 | |
108 | // main visual |
109 | |
110 | var tabs = scrollingTabs(jTopOrLeftTabs(horizontalLayout, |
111 | Posterized := withTools(isPosterized), |
112 | Regions := jscroll_centered_borderless(isRegions), |
113 | Script := scriptRunner.scriptAndResultPanel(), |
114 | "Test Screen" := testScreenPanel(), |
115 | Timings := withRightAlignedButtons(taTimings, |
116 | "Reset" := r resetTimings) |
117 | )); |
118 | |
119 | var vis = northAndCenter( |
120 | withSideAndTopMargin(uiURLs.urlBar()), |
121 | centerAndSouthOrEast(horizontalLayout, |
122 | horizontalLayout ? withMargin(tabs) : withSideMargin(tabs), |
123 | /*withMargin*/(borderlessScrollPane(jHigherScrollPane( |
124 | jfullcenter(vstack( |
125 | withLeftAndRightMargin(hstack( |
126 | dm_rcheckBox enabled("Watch screen"), |
127 | screenSelector.visualize(), |
128 | jlabel(" in "), |
129 | withLabelToTheRight("colors @ ", dm_spinner colors(2, 256)), |
130 | //withLabelToTheRight("p", dm_spinner pixelRows(1, 500)), |
131 | withLabelToTheRight("p", dm_powersOfTwoSpinner pixelRows(512)), |
132 | , /* speed info can also go here */ |
133 | )), |
134 | verticalStrut(2), |
135 | withRightMargin(jSpeedInfo) |
136 | ))))), |
137 | )); |
138 | setHorizontalMarginForAllButtons(vis, 4); |
139 | ret vis; |
140 | } |
141 | |
142 | S speedInfo() { |
143 | ret "FPS " + fps + " idle " + remainingMS + " ms"; |
144 | } |
145 | |
146 | S speedInfo_long() { |
147 | ret "Screen cam running at " + nFrames(fps) + "/second. " + n2(remainingMS) + " ms remaining per frame in first core."; |
148 | } |
149 | |
150 | void floodFill(BWImage img) { |
151 | BWImage_FastRegions ff = new(img); |
152 | //ff.tolerance(0); |
153 | ff.collectBounds(); |
154 | functionTimings.time("Regions", ff); |
155 | mainScreenRegions = ff; |
156 | regionHighlighter?.setRegions(ff); |
157 | if (isRegions != null && isRegions.isShowing_quick()) { |
158 | print("Showing regions image"); |
159 | isRegions.setImage_thisThread(ff.regionsImage()); |
160 | } |
161 | setEnclosingTabTitle(isRegions, nRegions(ff.regionCount())); |
162 | } |
163 | |
164 | bool useErrorHandling() { false; } |
165 | |
166 | S renderFunctionTimings() { |
167 | ret lines(ciSorted(map(functionTimings!, (f, avg) -> |
168 | firstToUpper(f) + ": " + n2(iround(nsToMicroseconds(avg!))) + " " + microSymbol() + "s (" + n2(iround(avg.n())) + ")"))); |
169 | } |
170 | |
171 | transient long _runScript_idx; |
172 | |
173 | void _runScript() { |
174 | long n = integralImages.elementCount(); |
175 | if (n > _runScript_idx) { |
176 | _runScript_idx = n; |
177 | |
178 | scriptRunner.parseAndRunOn(integralImages!); |
179 | } |
180 | } |
181 | |
182 | bool shouldRunScript() { |
183 | ret isShowing(scriptRunner.scpScriptResult); |
184 | } |
185 | |
186 | void stepAnimation { |
187 | if (!animate) ret; |
188 | if (animation == null) { |
189 | animation = new AnimatedLine; |
190 | animation.start(); |
191 | } |
192 | animation.nextFrame(); |
193 | var img = whiteImage(animation.w, animation.h); |
194 | animation.setGraphics(createGraphics(img)); |
195 | animation.paint(); |
196 | isTestScreen?.setImage(img); |
197 | |
198 | var ii = bwIntegralImage_withMeta(img); |
199 | testScreenScriptRunner.parseAndRunOn(ii); |
200 | } |
201 | |
202 | JComponent testScreenPanel() { |
203 | ret centerAndSouthWithMargin( |
204 | hsplit( |
205 | northAndCenterWithMargin(centerAndEastWithMargin( |
206 | jlabel("Input"), dm_fieldCheckBox animate()), |
207 | jscroll_centered_borderless(isTestScreen)), |
208 | |
209 | northAndCenterWithMargin(centerAndEastWithMargin( |
210 | jlabel("Output"), testScreenScriptRunner.lblScore), |
211 | testScreenScriptRunner.scpScriptResult) |
212 | ), |
213 | |
214 | testScreenScriptRunner.scriptInputField() |
215 | ); |
216 | } |
217 | |
218 | L popDownItems() { |
219 | ret ll(jCheckBoxMenuItem_dyn("Horizontal Layout", |
220 | -> horizontalLayout, |
221 | b -> setField(horizontalLayout := b))); |
222 | } |
223 | |
224 | void unvisualize {} // don't zero transient component fields |
225 | |
226 | void resetTimings { functionTimings.reset(); } |
227 | |
228 | // add tool side bar to image surface |
229 | JComponent withTools(ImageSurface is) { |
230 | new ImageSurface_PositionToolTip(is); |
231 | ret centerAndEastWithMargin(jscroll_centered_borderless(is), vstackWithSpacing(5, |
232 | jbutton("A"), |
233 | jbutton("B"), |
234 | jbutton("C"), |
235 | )); |
236 | } |
237 | } // end of module |
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1033683 |
Snippet name: | Gazelle Screen Cam / Gazelle 22 Module |
Eternal ID of this version: | #1033683/166 |
Text MD5: | 6b008d8afc204c1d7348605ead6a093d |
Transpilation MD5: | 7bfcb690878f6f7c5551a6d2ec38b7ad |
Author: | stefan |
Category: | javax / gazelle v |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-01-07 04:50:18 |
Source code size: | 7759 bytes / 237 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 448 / 2016 |
Version history: | 165 change(s) |
Referenced in: | [show references] |