/* mask editor buttons */
$('div#editMaskButton').click(function () {
var cameraId = $('#cameraSelect').val();
- var resolution = $('#resolutionSelect').val();
- if (!cameraId) {
- return;
+ var img = getCameraFrame(cameraId).find('img.camera')[0];
+ if (!img.naturalWidth || !img.naturalHeight) {
+ return runAlertDialog('Cannot edit the mask without a valid camera image!');
}
-
- if (!resolution) {
- /*
- * motion requires the mask file to be the same size as the
- * captured images; however for netcams we have no means to know in
- * advance the size of the stream; therefore, for netcams, we impose
- * here a standard fixed mask size, which WILL NOT WORK for netcam
- * streams of a different resolution, unless motion is patched accordingly
- */
- resolution = maskDefaultResolution;
- }
-
- resolution = resolution.split('x');
- var width = resolution[0];
- var height = resolution[1];
-
- enableMaskEdit(cameraId, width, height);
+
+ enableMaskEdit(cameraId, img.naturalWidth, img.naturalHeight);
});
$('div#saveMaskButton').click(function () {
disableMaskEdit();
var maskLines = [];
var bits, line;
+ maskLines.push(width);
+ maskLines.push(height);
+
for (y = 0; y < ny; y++) {
bits = [];
for (x = 0; x < nx; x++) {
line |= 1 << (maskWidth - 1 - i);
}
});
+
+ maskLines.push(line);
}
- maskLines.push(line);
-
$('#maskLinesEntry').val(maskLines.join(',')).change();
}
/* use mask lines to initialize the element matrix */
var line;
var maskLines = $('#maskLinesEntry').val() ? $('#maskLinesEntry').val().split(',').map(function (v) {return parseInt(v);}) : [];
-
+ maskLines = maskLines.slice(2);
+
for (y = 0; y < ny; y++) {
line = maskLines[y];
for (x = 0; x < nx; x++) {
_SPECIAL_COOKIE_NAMES = {'expires', 'domain', 'path', 'secure', 'httponly'}
MASK_WIDTH = 32
-MASK_DEFAULT_RESOLUTION = (640, 480)
DEV_NULL = open('/dev/null', 'w')
return urllib2.urlopen(*args, **kwargs)
-def build_editable_mask_file(camera_id, width, height, mask_lines):
+def build_editable_mask_file(camera_id, mask_lines, capture_width=None, capture_height=None):
+ width = mask_lines[0]
+ height = mask_lines[1]
+ mask_lines = mask_lines[2:]
+
logging.debug('building editable mask for camera with id %s (%sx%s)' %
(camera_id, width, height))
- width = width or MASK_DEFAULT_RESOLUTION[0]
- height = height or MASK_DEFAULT_RESOLUTION[1]
-
# horizontal rectangles
nx = MASK_WIDTH # number of rectangles
if width % nx:
dr.rectangle((nx * rw, ny * rh, nx * rw + rx - 1, ny * rh + ry - 1), fill=0)
file_name = os.path.join(settings.CONF_PATH, 'mask_%s.pgm' % camera_id)
- im.save(file_name, 'ppm')
+ # resize the image if necessary
+ if capture_width and capture_height and im.size != (capture_width, capture_height):
+ logging.debug('editable mask needs resizing from %sx%s to %sx%s' %
+ (im.size[0], im.size[1], capture_width, capture_height))
+
+ im = im.resize((capture_width, capture_height))
+
+ im.save(file_name, 'ppm')
+
return file_name
-def parse_editable_mask_file(camera_id, width, height):
- logging.debug('parsing editable mask for camera with id %s (%sx%s)' %
- (camera_id, width, height))
+def parse_editable_mask_file(camera_id, capture_width=None, capture_height=None):
+ # capture_width and capture_height arguments represent the current size
+ # of the camera image, as it might be different from that of the associated mask;
+ # they can be null (e.g. netcams)
+
+ file_name = os.path.join(settings.CONF_PATH, 'mask_%s.pgm' % camera_id)
+
+ logging.debug('parsing editable mask for camera with id %s: %s' % (camera_id, file_name))
+
+ # read the image file
+ try:
+ im = Image.open(file_name)
+
+ except Exception as e:
+ logging.error('failed to read mask file %s: %s' % (file_name, e))
+
+ # empty mask
+ return [0] * (MASK_WIDTH * 10)
+
+ if capture_width and capture_height:
+ # resize the image if necessary
+ if im.size != (capture_width, capture_height):
+ logging.debug('editable mask needs resizing from %sx%s to %sx%s' %
+ (im.size[0], im.size[1], capture_width, capture_height))
- # width and height arguments represent the current size of the camera image,
- # as it might be different from that of the associated mask
+ im = im.resize((capture_width, capture_height))
+
+ width, height = capture_width, capture_height
+
+ else:
+ logging.debug('using mask size from file: %sx%s' % (im.size[0], im.size[1]))
- width = width or MASK_DEFAULT_RESOLUTION[0]
- height = height or MASK_DEFAULT_RESOLUTION[1]
+ width, height = im.size
+
+ pixels = list(im.getdata())
# horizontal rectangles
nx = MASK_WIDTH # number of rectangles
rw = width / nx # rectangle width
# vertical rectangles
- ny = mask_height = height * MASK_WIDTH / width # number of rectangles
+ ny = height * MASK_WIDTH / width # number of rectangles
if height % ny:
ny -= 1
ry = height % ny # remainder
rh = height / ny # rectangle height
- file_name = os.path.join(settings.CONF_PATH, 'mask_%s.pgm' % camera_id)
-
- # read the image file
- try:
- im = Image.open(file_name)
-
- except Exception as e:
- logging.error('failed to read mask file %s: %s' % (file_name, e))
-
- # empty mask
- return [0] * mask_height
-
- # resize the image if necessary
- if im.size != (width, height):
- logging.debug('editable mask needs resizing from %sx%s to %sx%s' %
- (im.size[0], im.size[1], width, height))
-
- im = im.resize((width, height))
-
- pixels = list(im.getdata())
-
# parse the image contents and build the mask lines
- mask_lines = []
+ mask_lines = [width, height]
for y in xrange(ny):
bits = []
for x in xrange(nx):