forked from dscho/fiji
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Record_Window.py
205 lines (184 loc) · 5.72 KB
/
Record_Window.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# Albert Cardona 20090418.
# Released under the General Public License v2.0
#
# Take snapshots of a user-specified window over time,
# and then make an image stack of of them all.
#
# In the dialog, 0 frames mean infinite recording, to be interrupted by ESC
# pressed on the ImageJ toolbar or other frames with the same listener.
#
# If not saving to file, then you are limited to RAM.
#
# When done, a stack or a virtual stack opens.
import thread
import time
import sys
from java.awt import Robot, Rectangle, Frame
from java.awt.image import BufferedImage
from javax.swing import SwingUtilities
from java.io import File, FilenameFilter
from java.util.concurrent import Executors
from java.util import Arrays
class PrintAll(Runnable):
def __init__(self, frame, g):
self.frame = frame
self.g = g
def run(self):
self.frame.printAll(self.g)
def snapshot(frame, box):
bi = BufferedImage(box.width, box.height, BufferedImage.TYPE_INT_RGB)
g = bi.createGraphics()
g.translate(-box.x, -box.y)
#all black! # frame.paintAll(g)
#only swing components! # frame.paint(g)
#only swing components! # frame.update(g)
#together, also only swing and with errors
##frame.update(g)
##frame.paint(g)
# locks the entire graphics machinery # frame.printAll(g)
# Finally, the right one:
SwingUtilities.invokeAndWait(PrintAll(frame, g))
return bi
class Saver(Runnable):
def __init__(self, i, dir, bounds, borders, img, insets):
self.i = i
self.dir = dir
self.bounds = bounds
self.borders = borders
self.img = img
self.insets = insets
def run(self):
System.out.println("run")
# zero-pad up to 10 digits
bi = None
try:
title = str(self.i)
while len(title) < 10:
title = '0' + title
bi = BufferedImage(self.bounds.width, self.bounds.height, BufferedImage.TYPE_INT_RGB)
g = bi.createGraphics()
g.drawImage(self.borders, 0, 0, None)
g.drawImage(self.img, self.insets.left, self.insets.top, None)
FileSaver(ImagePlus(title, ColorProcessor(bi))).saveAsTiff(self.dir + title + '.tif')
except Exception, e:
print e
e.printStackTrace()
if bi is not None: bi.flush()
self.img.flush()
class TifFilter(FilenameFilter):
def accept(self, dir, name):
return name.endswith('.tif')
def run(title):
gd = GenericDialog('Record Window')
gd.addMessage("Maximum number of frames to record.\nZero means infinite, interrupt with ESC key.")
gd.addNumericField('Max. frames:', 50, 0)
gd.addNumericField('Milisecond interval:', 300, 0)
gd.addSlider('Start in (seconds):', 0, 20, 5)
frames = []
titles = []
for f in Frame.getFrames():
if f.isEnabled() and f.isVisible():
frames.append(f)
titles.append(f.getTitle())
gd.addChoice('Window:', titles, titles[0])
gd.addCheckbox("To file", False)
gd.showDialog()
if gd.wasCanceled():
return
n_frames = int(gd.getNextNumber())
interval = gd.getNextNumber() / 1000.0 # in seconds
frame = frames[gd.getNextChoiceIndex()]
delay = int(gd.getNextNumber())
tofile = gd.getNextBoolean()
dir = None
if tofile:
dc = DirectoryChooser("Directory to store image frames")
dir = dc.getDirectory()
if dir is None:
return # dialog canceled
snaps = []
borders = None
executors = Executors.newFixedThreadPool(1)
try:
while delay > 0:
IJ.showStatus('Starting in ' + str(delay) + 's.')
time.sleep(1) # one second
delay -= 1
IJ.showStatus('Capturing frame borders...')
bounds = frame.getBounds()
robot = Robot()
frame.toFront()
time.sleep(0.5) # half a second
borders = robot.createScreenCapture(bounds)
IJ.showStatus("Recording " + frame.getTitle())
# Set box to the inside borders of the frame
insets = frame.getInsets()
box = bounds.clone()
box.x = insets.left
box.y = insets.top
box.width -= insets.left + insets.right
box.height -= insets.top + insets.bottom
start = System.currentTimeMillis() / 1000.0 # in seconds
last = start
intervals = []
real_interval = 0
i = 1
fus = None
if tofile:
fus = []
# 0 n_frames means continuous acquisition
while 0 == n_frames or (len(snaps) < n_frames and last - start < n_frames * interval):
now = System.currentTimeMillis() / 1000.0 # in seconds
real_interval = now - last
if real_interval >= interval:
last = now
img = snapshot(frame, box)
if tofile:
fus.append(executors.submit(Saver(i, dir, bounds, borders, img, insets))) # will flush img
i += 1
else:
snaps.append(img)
intervals.append(real_interval)
else:
time.sleep(interval / 5)
# interrupt capturing:
if IJ.escapePressed():
IJ.showStatus("Recording user-interrupted")
break
# debug:
#print "insets:", insets
#print "bounds:", bounds
#print "box:", box
#print "snap dimensions:", snaps[0].getWidth(), snaps[0].getHeight()
# Create stack
stack = None;
if tofile:
for fu in snaps: fu.get() # wait on all
stack = VirtualStack(bounds.width, bounds.height, None, dir)
files = File(dir).list(TifFilter())
Arrays.sort(files)
for f in files:
stack.addSlice(f)
else:
stack = ImageStack(bounds.width, bounds.height, None)
t = 0
for snap,real_interval in zip(snaps,intervals):
bi = BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_RGB)
g = bi.createGraphics()
g.drawImage(borders, 0, 0, None)
g.drawImage(snap, insets.left, insets.top, None)
stack.addSlice(str(IJ.d2s(t, 3)), ImagePlus('', bi).getProcessor())
t += real_interval
snap.flush()
bi.flush()
borders.flush()
ImagePlus(frame.getTitle() + " recording", stack).show()
IJ.showStatus('Done recording ' + frame.getTitle())
except Exception, e:
print "Some error ocurred:"
print e.printStackTrace()
IJ.showStatus('')
if borders is not None: borders.flush()
for snap in snaps: snap.flush()
executors.shutdown()
thread.start_new_thread(run, ("Do it",))