diff --git a/examples/capture/api.js b/examples/capture/api.js
index 7019a36b..c241bc3b 100644
--- a/examples/capture/api.js
+++ b/examples/capture/api.js
@@ -1,210 +1,304 @@
jQuery(document).ready(function() {
+ /* create a modal dialog; buttons defined as a
+ * nested array of buttn names and code to be run:
+ * [["Save",function(){}],["Cancel",$('.modal').hide()]]
+ */
+ $W.dialog = function(title, body, options) {
+ html = '
";
+ $("body").append(html);
+ };
+
+ $W.calibrate = function(id, x1, w1, x2, w2) {
+ if ($W.interface == "analyze") {
+ window.location =
+ "/spectra/calibrate/" +
+ $W.spectrum_id +
+ "?x1=" +
+ x1 +
+ "&w1=" +
+ w1 +
+ "&x2=" +
+ x2 +
+ "&w2=" +
+ w2;
} else {
- isfalse()
+ $.ajax({
+ url:
+ "/spectra/calibrate/" +
+ $W.spectrum_id +
+ "?x1=" +
+ x1 +
+ "&w1=" +
+ w1 +
+ "&x2=" +
+ x2 +
+ "&w2=" +
+ w2,
+ type: "GET",
+ success: function(result) {
+ $W.notify(
+ "The spectrum with id " + id + " was calibrated successfully."
+ );
+ }
+ });
}
- },500)
-}
+ };
+
+ // an abstract measure of a spectrum's local contrast, sampling every pixels, and only counting measured slope >1; used as a metric to determine if it's likely to be a CFL. Needs testing against lots of spectra & CFLs
+ $W.contrast = function(res) {
+ var sum = 0;
+ res = res || 10;
+ for (var i = res; i < $W.data[0].data.length; i += res) {
+ // added /res to make it about slope
+ slope =
+ Math.abs(
+ parseInt($W.data[0].data[i - res][1]) -
+ parseInt($W.data[0].data[i][1])
+ ) / res;
+ // only add it if slope is greater than 1
+ if (slope > 1) sum += slope;
+ }
+ return sum / $W.data[0].data.length;
+ };
+
+ // watch and alert if contrast is high enough to likely be a CFL
+ $W.observe_contrast = function(threshold, istrue, isfalse) {
+ threshold = threshold || 0.04;
+ setInterval(function() {
+ if ($W.contrast() > threshold) {
+ istrue();
+ } else {
+ isfalse();
+ }
+ }, 500);
+ };
-$W.run_macro = function(author,macro) {
- $('body').append("")
- $('#macrosmodal').modal('hide')
- $('a').popover('hide')
-}
+ $W.run_macro = function(author, macro) {
+ $("body").append(
+ ""
+ );
+ $("#macrosmodal").modal("hide");
+ $("a").popover("hide");
+ };
-// These are not really useful anymore:
+ // These are not really useful anymore:
-// Needs rewriting for multiple macros:
-$W.load_macro = function(macro) {
+ // Needs rewriting for multiple macros:
+ $W.load_macro = function(macro) {
//eval("$W.macro = {"+$('#code').val()+"}")
- $W.macro = macro
- $W.macro.setup()
-}
-
-// Static macros storage
-$W.macros = {
- download_image: {
- author: "warren",
- type: "capture", // or "analyze"
- link: "http://unterbahn.com",
- // code to run on startup
- setup: function() {
- window.open($W.canvas.toDataURL(),'_newtab').focus() // this may not work if popups are blocked
+ $W.macro = macro;
+ $W.macro.setup();
+ };
+
+ // Static macros storage
+ $W.macros = {
+ download_image: {
+ author: "warren",
+ type: "capture", // or "analyze"
+ link: "http://unterbahn.com",
+ // code to run on startup
+ setup: function() {
+ window.open($W.canvas.toDataURL(), "_newtab").focus(); // this may not work if popups are blocked
+ },
+ // code to run every frame
+ draw: function() {}
},
- // code to run every frame
- draw: function() {
- }
- },
- /*
+ /*
Attempts to determine if the spectrum is of a CFL by checking if the
array i.e. [1,1.4,1.68,1.45] is within of array
*/
- is_cfl: {
- author: "warren",
- type: "analyze",
- link: "none",
- setup: function(threshold,reference) {
- threshold = threshold || 0.1 // 10%
- ratios = $W.macros.get_peak_pattern.setup()
- reference = reference || [1, 1.7692307692307692, 1.6923076923076923, 1.3846153846153846]
- var is_cfl = true
- for (i = 0; i < reference.length; i++) {
- if (Math.abs(1-ratios[i]/reference[i]) > threshold) is_cfl = false
- }
- // try looking for a CFL which is missing its first blue line
- var is_offset_cfl = true
- for (i = 0; i < reference.length-1; i++) {
- if (Math.abs(1-ratios[i]/reference[i+1]) > threshold) is_offset_cfl = false
- }
- // have to try backwards order too!
+ is_cfl: {
+ author: "warren",
+ type: "analyze",
+ link: "none",
+ setup: function(threshold, reference) {
+ threshold = threshold || 0.1; // 10%
+ ratios = $W.macros.get_peak_pattern.setup();
+ reference = reference || [
+ 1,
+ 1.7692307692307692,
+ 1.6923076923076923,
+ 1.3846153846153846
+ ];
+ var is_cfl = true;
+ for (i = 0; i < reference.length; i++) {
+ if (Math.abs(1 - ratios[i] / reference[i]) > threshold)
+ is_cfl = false;
+ }
+ // try looking for a CFL which is missing its first blue line
+ var is_offset_cfl = true;
+ for (i = 0; i < reference.length - 1; i++) {
+ if (Math.abs(1 - ratios[i] / reference[i + 1]) > threshold)
+ is_offset_cfl = false;
+ }
+ // have to try backwards order too!
- return is_cfl || is_offset_cfl
- }
- },
+ return is_cfl || is_offset_cfl;
+ }
+ },
- /* returns ratios of distance between peaks, starting with first gap = 1; beware of assuming linearity
+ /* returns ratios of distance between peaks, starting with first gap = 1; beware of assuming linearity
Also be aware that order may be reversed
*/
- get_peak_pattern: {
- author: "warren",
- type: "analyze",
- link: "none",
- /* max width of peaks to search for, whether to return only wavelengths */
- setup: function(min_width,min_height,min_slope,threshold,pixels,wavelengths) {
- peaks = $W.macros.detect_peaks.setup(min_width,min_height,min_slope,threshold,pixels,wavelengths)
- var ratios = []
- var base = peaks[1]['index']-peaks[0]['index']
- for (var i = 0; i < peaks.length-1; i++) {
- ratios.push((peaks[i+1]['index']-peaks[i]['index'])/base)
+ get_peak_pattern: {
+ author: "warren",
+ type: "analyze",
+ link: "none",
+ /* max width of peaks to search for, whether to return only wavelengths */
+ setup: function(
+ min_width,
+ min_height,
+ min_slope,
+ threshold,
+ pixels,
+ wavelengths
+ ) {
+ peaks = $W.macros.detect_peaks.setup(
+ min_width,
+ min_height,
+ min_slope,
+ threshold,
+ pixels,
+ wavelengths
+ );
+ var ratios = [];
+ var base = peaks[1]["index"] - peaks[0]["index"];
+ for (var i = 0; i < peaks.length - 1; i++) {
+ ratios.push((peaks[i + 1]["index"] - peaks[i]["index"]) / base);
+ }
+ return ratios;
}
- return ratios
- }
- },
+ },
- /*
+ /*
improved version of detect_peaks which iterates from the top down (tallest peaks first)
instead of left to right, and can stop at a named # of peaks if needed
width of peaks to search for, whether to return only wavelengths
returns results to an arbitrary 2 decimal points
an alternative might be to search for peaks based not on continuousness of slope (as here) but by *angle* of slope -- only 'sharp' peaks
*/
- detect_peaks: {
- author: "warren",
- type: "analyze",
- link: "https://gist.github.com/jywarren/6020668",
- setup: function(min_width,min_height,min_slope,threshold,pixels,wavelengths) {
- min_width = min_width || 7 // min peak width to search for
- min_height = min_height || 20 // min peak width to search for
- min_slope = 3 // minimum peak slope to search for, where 1 = 45 deg
- threshold = threshold || min_width // ignore peaks within distance of each other
- pixels = pixels || $W.spectrum.lines
- wavelengths = wavelengths || false // return only an array of wavelengths
-
- var peaks = []
- var peak_wavelengths = []
-
- // recursively checks if slope is of consistent direction on each side of a given peak, recursing outwards until max/2
- // swap comparisons if you want to search for valleys instead of peaks
- var check_slope = function(dist,i) {
- if (dist > min_width/2) return true
- else if (i+dist >= pixels.length || i-dist <= 0) return false // if we hit the beginning or end of the image
- else return (check_slope(dist+1,i)) && pixels[i+dist]['average'] <= pixels[i]['average'] && pixels[i-dist]['average'] <= pixels[i]['average']
- }
+ detect_peaks: {
+ author: "warren",
+ type: "analyze",
+ link: "https://gist.github.com/jywarren/6020668",
+ setup: function(
+ min_width,
+ min_height,
+ min_slope,
+ threshold,
+ pixels,
+ wavelengths
+ ) {
+ min_width = min_width || 7; // min peak width to search for
+ min_height = min_height || 20; // min peak width to search for
+ min_slope = 3; // minimum peak slope to search for, where 1 = 45 deg
+ threshold = threshold || min_width; // ignore peaks within distance of each other
+ pixels = pixels || $W.spectrum.lines;
+ wavelengths = wavelengths || false; // return only an array of wavelengths
- // checks if the peak is within pixels of a known peak
- var is_near_existing_peak = function(target_peak) {
- var is_near = false
- $.each(peaks,function(i,peak) {
- if (Math.abs(peak['index']-target_peak) < threshold) is_near = true
- })
- return is_near
- }
+ var peaks = [];
+ var peak_wavelengths = [];
+
+ // recursively checks if slope is of consistent direction on each side of a given peak, recursing outwards until max/2
+ // swap comparisons if you want to search for valleys instead of peaks
+ var check_slope = function(dist, i) {
+ if (dist > min_width / 2) return true;
+ else if (i + dist >= pixels.length || i - dist <= 0) return false;
+ // if we hit the beginning or end of the image
+ else
+ return (
+ check_slope(dist + 1, i) &&
+ pixels[i + dist]["average"] <= pixels[i]["average"] &&
+ pixels[i - dist]["average"] <= pixels[i]["average"]
+ );
+ };
+
+ // checks if the peak is within pixels of a known peak
+ var is_near_existing_peak = function(target_peak) {
+ var is_near = false;
+ $.each(peaks, function(i, peak) {
+ if (Math.abs(peak["index"] - target_peak) < threshold)
+ is_near = true;
+ });
+ return is_near;
+ };
- // scan entire graph for highest values, starting at top and scanning downwards
- // This is an opportunity to limit search to n total peaks
- // Also, due to a dumb rounding bug, average values can exceed 255; up to 257 i believe
- for (var height = 259; height >= 0; height--) {
- for (var i = parseInt(min_width/2); i < pixels.length-parseInt(min_width/2); i++) {
- if (pixels[i]['average'] >= height && pixels[i]['average'] < height+1 && !is_near_existing_peak(i)) {
- // determine how large a peak is and adds it to peaks array if it's wider than and taller than
- if (check_slope(1,i) && (i+min_width < pixels.length && i-min_width > 0) && Math.abs(pixels[i]['average']-pixels[i+min_width]['average'])/min_width >= min_slope && Math.abs(pixels[i]['average']-pixels[i-min_width]['average'])/min_width >= min_slope && pixels[i]['average']-pixels[i-min_width]['average'] > min_height && pixels[i]['average']-pixels[i+min_width]['average'] > min_height) {
- // it's a peak pixel, add it to peak pixel list
- peaks.push(pixels[i]) // here, adding the entire pixel object, including separate rgb and wavelength values
- peaks[peaks.length-1]['index'] = i // save the pixel index too
- // be aware of non-calibrated spectra
- peak_wavelengths.push(parseFloat(pixels[i]['wavelength'].toFixed(2))) // here, adding just the rounded wavelength
- $W.plot.highlight(0,i) // highlight the peak on the graph
- }
+ // scan entire graph for highest values, starting at top and scanning downwards
+ // This is an opportunity to limit search to n total peaks
+ // Also, due to a dumb rounding bug, average values can exceed 255; up to 257 i believe
+ for (var height = 259; height >= 0; height--) {
+ for (
+ var i = parseInt(min_width / 2);
+ i < pixels.length - parseInt(min_width / 2);
+ i++
+ ) {
+ if (
+ pixels[i]["average"] >= height &&
+ pixels[i]["average"] < height + 1 &&
+ !is_near_existing_peak(i)
+ ) {
+ // determine how large a peak is and adds it to peaks array if it's wider than and taller than
+ if (
+ check_slope(1, i) &&
+ (i + min_width < pixels.length && i - min_width > 0) &&
+ Math.abs(
+ pixels[i]["average"] - pixels[i + min_width]["average"]
+ ) /
+ min_width >=
+ min_slope &&
+ Math.abs(
+ pixels[i]["average"] - pixels[i - min_width]["average"]
+ ) /
+ min_width >=
+ min_slope &&
+ pixels[i]["average"] - pixels[i - min_width]["average"] >
+ min_height &&
+ pixels[i]["average"] - pixels[i + min_width]["average"] >
+ min_height
+ ) {
+ // it's a peak pixel, add it to peak pixel list
+ peaks.push(pixels[i]); // here, adding the entire pixel object, including separate rgb and wavelength values
+ peaks[peaks.length - 1]["index"] = i; // save the pixel index too
+ // be aware of non-calibrated spectra
+ peak_wavelengths.push(
+ parseFloat(pixels[i]["wavelength"].toFixed(2))
+ ); // here, adding just the rounded wavelength
+ $W.plot.highlight(0, i); // highlight the peak on the graph
+ }
+ }
}
}
- }
- // sort left to right
+ // sort left to right
+
+ peaks = peaks.sort(function(a, b) {
+ return a["index"] - b["index"];
+ });
+ peak_wavelengths = peak_wavelengths.sort(function(a, b) {
+ return a - b;
+ });
- peaks = peaks.sort(function(a,b) { return a['index'] - b['index'] })
- peak_wavelengths = peak_wavelengths.sort(function(a,b) { return a - b })
-
- if (wavelengths) return peak_wavelengths
- else return peaks
+ if (wavelengths) return peak_wavelengths;
+ else return peaks;
+ }
}
- }
-}
-})
+ };
+});
diff --git a/examples/capture/capture.js b/examples/capture/capture.js
index 955999ae..1b912986 100644
--- a/examples/capture/capture.js
+++ b/examples/capture/capture.js
@@ -1,16 +1,36 @@
// window.webcam.getCameraList()
-flotoptions = {"crosshair":{"mode":"x"},"series":{"lines":{"show":true,"lineWidth":1}},"yaxis":{"show":true,"max":100,"min":0},"xaxis":{"show":false},"shadowSize":0,"threshold":{"below":0,"color":"#a00"},"grid":{"clickable":true,"hoverable":true,"borderWidth":0,"color":"#ccc","backgroundColor":"#111"},"colors":["#ffffff","rgba(255,0,0,0.3)","rgba(0,255,0,0.3)","rgba(0,0,255,0.3)","#ffff00"]}
-
- flotoptions.grid = {
+flotoptions = {
+ crosshair: { mode: "x" },
+ series: { lines: { show: true, lineWidth: 1 } },
+ yaxis: { show: true, max: 100, min: 0 },
+ xaxis: { show: false },
+ shadowSize: 0,
+ threshold: { below: 0, color: "#a00" },
+ grid: {
clickable: true,
- hoverable:true,
+ hoverable: true,
borderWidth: 0,
color: "#ccc",
backgroundColor: "#111"
- }
- flotoptions.colors = [ "#ccc", "#E02130", "#FAB243", "#429867", "#2B5166" ]//, "#482344" ]
-
+ },
+ colors: [
+ "#ffffff",
+ "rgba(255,0,0,0.3)",
+ "rgba(0,255,0,0.3)",
+ "rgba(0,0,255,0.3)",
+ "#ffff00"
+ ]
+};
+
+flotoptions.grid = {
+ clickable: true,
+ hoverable: true,
+ borderWidth: 0,
+ color: "#ccc",
+ backgroundColor: "#111"
+};
+flotoptions.colors = ["#ccc", "#E02130", "#FAB243", "#429867", "#2B5166"]; //, "#482344" ]
$W = {
data: null,
@@ -27,86 +47,95 @@ $W = {
waterfall_height: 150,
scale_h: 1,
scale_w: 1,
+ loadingfromPi: false,
// width: 1280,
// height: 720,
frame: 0,
initialize: function(args) {
- this.mobile = args['mobile'] || false
- this.flipped = args['flipped'] == true || false
- this.interface = args['interface'] || false
- this.mode = args['mode'] || 'combined'
- flotoptions.colors = [ "#ffffff", "rgba(255,0,0,0.3)", "rgba(0,255,0,0.3)", "rgba(0,0,255,0.3)", "#ffff00"]
- this.calibrated = args['calibrated'] || false
- this.width = args['width'] || this.width
- this.height = args['height'] || this.height
- if (args['height']) {
- this.options.height = args['height']
- this.options.width = args['width']
+ this.mobile = args["mobile"] || false;
+ this.flipped = args["flipped"] == true || false;
+ this.interface = args["interface"] || false;
+ this.mode = args["mode"] || "combined";
+ flotoptions.colors = [
+ "#ffffff",
+ "rgba(255,0,0,0.3)",
+ "rgba(0,255,0,0.3)",
+ "rgba(0,0,255,0.3)",
+ "#ffff00"
+ ];
+ this.calibrated = args["calibrated"] || false;
+ this.width = args["width"] || this.width;
+ this.height = args["height"] || this.height;
+ if (args["height"]) {
+ this.options.height = args["height"];
+ this.options.width = args["width"];
}
if (args.video_row) {
this.sample_start_row = args.video_row;
} else {
// this is camera sample row, not saved image sample row!
- this.sample_start_row = localStorage.getItem('sw:samplestartrow') || this.width/2;
+ this.sample_start_row =
+ localStorage.getItem("sw:samplestartrow") || this.width / 2;
}
- this.setSampleRow(this.sample_start_row)
+ this.setSampleRow(this.sample_start_row);
- getUserMedia(this.options, this.success, this.deviceError)
+ getUserMedia(this.options, this.success, this.deviceError);
- window.webcam = this.options
- this.canvas = document.getElementById("canvas")
- $('canvas').width = this.width+"px"
- this.canvas.width = this.width
- this.canvas.height = this.waterfall_height
- this.ctx = this.canvas.getContext("2d")
+ window.webcam = this.options;
+ this.canvas = document.getElementById("canvas");
+ $("canvas").width = this.width + "px";
+ this.canvas.width = this.width;
+ this.canvas.height = this.waterfall_height;
+ this.ctx = this.canvas.getContext("2d");
this.image = this.ctx.getImageData(0, 0, this.width, this.height);
// create canvas for the sidebar preview if there's a "preview" canvas element:
- if ($('#preview').length > 0) {
- this.preview_ctx = $('#preview')[0].getContext('2d')
+ if ($("#preview").length > 0) {
+ this.preview_ctx = $("#preview")[0].getContext("2d");
}
setInterval($W.alert_overexposure, 500); // every 0.5 seconds
setInterval(function() {
-
- $W.getRecentCalibrations('.select-calibration');
-
+ $W.getRecentCalibrations(".select-calibration");
}, 10000); // every 10 seconds
- $('.btn-switch-calibration-configure').click(function() {
- window.location = "/capture?calibration_id=" + $('.select-calibration-configure').val()
+ $(".btn-switch-calibration-configure").click(function() {
+ window.location =
+ "/capture?calibration_id=" + $(".select-calibration-configure").val();
});
- $('.btn-switch-calibration-capture').click(function() {
- window.location = "/capture?calibration_id=" + $('.select-calibration-capture').val()
+ $(".btn-switch-calibration-capture").click(function() {
+ window.location =
+ "/capture?calibration_id=" + $(".select-calibration-capture").val();
});
- $W.data = [{label: "webcam",data:[]}]
- if ($('video')[0]) {
- $('video')[0].width = "320"
- $('video')[0].height = "240"
+ $W.data = [{ label: "webcam", data: [] }];
+ if ($("video")[0]) {
+ $("video")[0].width = "320";
+ $("video")[0].height = "240";
} else {
- $('video').width = "320"
- $('video').height = "240"
+ $("video").width = "320";
+ $("video").height = "240";
}
},
- success: function (stream) {
+ success: function(stream) {
//console.log('success')
- if ($W.options.context === 'webrtc') {
- $('#heightIndicator').show()
- $('#webcam-msg').hide()
- var video = $W.options.videoEl, vendorURL = window.URL || window.webkitURL;
- window.stream = stream
- window.video = video
+ if ($W.options.context === "webrtc") {
+ $("#heightIndicator").show();
+ $("#webcam-msg").hide();
+ var video = $W.options.videoEl,
+ vendorURL = window.URL || window.webkitURL;
+ window.stream = stream;
+ window.video = video;
//if (!!stream) {
// video.src = null;
// stream.stop();
//}
if (navigator.mozGetUserMedia) video.mozSrcObject = stream;
else video.srcObject = stream;
- video.onerror = function (e) {
+ video.onerror = function(e) {
stream.stop();
};
//video.play()
@@ -117,10 +146,10 @@ $W = {
}
} else {
//flash context
- console.log('flash or something else')
+ console.log("flash or something else");
}
},
- deviceError: function (error) {
+ deviceError: function(error) {
//console.log(error)
},
// options contains the configuration information for the shim
@@ -129,9 +158,8 @@ $W = {
// events that are triggered onCapture and onSave (for the fallback)
// and so on.
options: {
-
- "audio": false,
- "video": true,
+ audio: false,
+ video: true,
// the element (by id) you wish to apply
el: "webcam",
@@ -151,42 +179,43 @@ $W = {
quality: 100,
context: "",
- debug: function () {},
+ debug: function() {},
// callback for capturing the fallback stream
- onCapture: function () {
+ onCapture: function() {
window.webcam.save();
},
- onTick: function () {},
+ onTick: function() {},
// callback for saving the stream, useful for
// relaying data further.
- onSave: function (data) {
+ onSave: function(data) {
// in progress for Flash now
// seems to execute 240 times... once for each column?
- var col = data.split(";"),
- img = $W.canvas.getContext('2d').getImageData(0, 0, this.width, this.height);
- tmp = null,
- w = this.width,
- h = this.height;
-
- for (var i = 0; i < w; i++) {
- tmp = parseInt(col[i], 10);
- img.data[$W.pos + 0] = (tmp >> 16) & 0xff;
- img.data[$W.pos + 1] = (tmp >> 8) & 0xff;
- img.data[$W.pos + 2] = tmp & 0xff;
- img.data[$W.pos + 3] = 0xff;
- $W.pos += 4;
- }
+ if ($W.loadingfromPi == false) {
+ var col = data.split(";"),
+ img = $W.canvas
+ .getContext("2d")
+ .getImageData(0, 0, this.width, this.height);
+ (tmp = null), (w = this.width), (h = this.height);
+
+ for (var i = 0; i < w; i++) {
+ tmp = parseInt(col[i], 10);
+ img.data[$W.pos + 0] = (tmp >> 16) & 0xff;
+ img.data[$W.pos + 1] = (tmp >> 8) & 0xff;
+ img.data[$W.pos + 2] = tmp & 0xff;
+ img.data[$W.pos + 3] = 0xff;
+ $W.pos += 4;
+ }
- if ($W.pos >= 4 * w * $W.sample_height) {
- $W.canvas.getContext('2d').putImageData(img, 0, 0);
- $W.ctx.drawImage(img, 0, 0);
- $W.pos = 0;
+ if ($W.pos >= 4 * w * $W.sample_height) {
+ $W.canvas.getContext("2d").putImageData(img, 0, 0);
+ $W.ctx.drawImage(img, 0, 0);
+ $W.pos = 0;
+ }
}
-
},
- onLoad: function () {}
+ onLoad: function() {}
},
// Draws the appropriate pixels onto the top row of the waterfall.
@@ -196,318 +225,379 @@ $W = {
// draw the new data on the top row of pixels of the canvas, overwriting what's there now
if ($W.mobile) {
// this is only for the deprecated mobile version
- $W.ctx.scale(3,1)
- $W.ctx.translate($('video').height()/2,0)
- if (!$W.rotated) $W.ctx.rotate(Math.PI/2)
- $W.ctx.drawImage(video, -$W.sample_start_row/4, -$W.height/2);
+ $W.ctx.scale(3, 1);
+ $W.ctx.translate($("video").height() / 2, 0);
+ if (!$W.rotated) $W.ctx.rotate(Math.PI / 2);
+ $W.ctx.drawImage(video, -$W.sample_start_row / 4, -$W.height / 2);
} else {
if ($W.flipped) {
- $W.ctx.translate($W.width,0)
- $W.ctx.scale(-1,1)
+ $W.ctx.translate($W.width, 0);
+ $W.ctx.scale(-1, 1);
}
- $W.ctx.scale($W.scale_h,$W.scale_w)
+ $W.ctx.scale($W.scale_h, $W.scale_w);
if ($W.rotated) {
-
// these lines may not be working properly for high-resolution cameras on mobile devices?
// or maybe odd aspect ratios. Do we need to be accounting for the incoming video size?
- $W.ctx.scale($W.width/$W.height,$W.width/$('#canvas').height())
- $W.ctx.translate($W.height,-$W.sample_start_row)
+ $W.ctx.scale($W.width / $W.height, $W.width / $("#canvas").height());
+ $W.ctx.translate($W.height, -$W.sample_start_row);
- $W.ctx.rotate(Math.PI/2)
- $W.ctx.drawImage(video,0,0)
+ $W.ctx.rotate(Math.PI / 2);
+ $W.ctx.drawImage(video, 0, 0);
} else {
- $W.ctx.drawImage(video,0,-$W.sample_start_row)
+ $W.ctx.drawImage(video, 0, -$W.sample_start_row);
}
// testing line; go to //spectralworkbench.org/capture?debug=true
- if ($W.debug_tmp) $W.debug_log = "$W.height="+$W.height+" $W.width="+$W.width+" #canvas height="+$('#canvas').height()
+ if ($W.debug_tmp)
+ $W.debug_log =
+ "$W.height=" +
+ $W.height +
+ " $W.width=" +
+ $W.width +
+ " #canvas height=" +
+ $("#canvas").height();
}
},
getRow: function(y) {
- $W.frame += 1
- if ($W.options.context === 'webrtc') {
- var video = $('video')[0];
+ $W.frame += 1;
+ if ($W.options.context === "webrtc") {
+ var video = $("video")[0];
// Grab the existing canvas:
- var saved = $W.excerptCanvas(0,0,$W.width,$W.height,$W.ctx).getImageData(0,0,$W.width,$W.height)
+ var saved = $W
+ .excerptCanvas(0, 0, $W.width, $W.height, $W.ctx)
+ .getImageData(0, 0, $W.width, $W.height);
// manipulate the canvas to get the image to copy onto the canvas in the right orientation
- $W.ctx.save()
- $W.getCrossSection(video)
- $W.ctx.restore()
+ $W.ctx.save();
+ $W.getCrossSection(video);
+ $W.ctx.restore();
// draw old data 1px below new row of data:
- $W.ctx.putImageData(saved,0,1)
- } else if($W.options.context === 'flash'){
+ $W.ctx.putImageData(saved, 0, 1);
+ } else if ($W.options.context === "flash") {
window.webcam.capture();
} else {
- console.log('No context was supplied to getSnapshot()');
+ console.log("No context was supplied to getSnapshot()");
}
// populate the sidebar preview if there's a "preview" element:
- if ($('#preview').length > 0) {
- $W.preview_ctx.canvas.width = $('#preview').width()
- $W.preview_ctx.canvas.height = $('#preview').width()*0.75
- $('#preview').height($('#preview').width()*0.75)
+ if ($("#preview").length > 0) {
+ $W.preview_ctx.canvas.width = $("#preview").width();
+ $W.preview_ctx.canvas.height = $("#preview").width() * 0.75;
+ $("#preview").height($("#preview").width() * 0.75);
if ($W.flipped) {
- $W.preview_ctx.translate($('#preview').width(),0)
- $W.preview_ctx.scale(-1,1)
+ $W.preview_ctx.translate($("#preview").width(), 0);
+ $W.preview_ctx.scale(-1, 1);
}
- $W.preview_ctx.drawImage($('video')[0],0,0,$('#preview').width(),$('#preview').width()*0.75)
- if ($W.rotated != true) $("#heightIndicatorPrev").width($('#sidebar').width())
- $W.resetHeightIndicators(false)
+ if ($W.loadingfromPi) var videoSrc = $W.piImage;
+ else var videoSrc = $("video")[0];
+ $W.preview_ctx.drawImage(
+ videoSrc,
+ 0,
+ 0,
+ $("#preview").width(),
+ $("#preview").width() * 0.75
+ );
+ if ($W.rotated != true)
+ $("#heightIndicatorPrev").width($("#sidebar").width());
+ $W.resetHeightIndicators(false);
}
// get the slice of data
- img = $W.ctx.getImageData(0,0,$W.canvas.width,$W.sample_height)
+ img = $W.ctx.getImageData(0, 0, $W.canvas.width, $W.sample_height);
// use it to generate a graph
if ($W.mode == "average") {
- $W.data[0] = {label: "Webcam",data:[]}
+ $W.data[0] = { label: "Webcam", data: [] };
} else if ($W.mode == "rgb") {
- $W.data[0] = {label: "R",data:[]}
- $W.data[1] = {label: "G",data:[]}
- $W.data[2] = {label: "B",data:[]}
+ $W.data[0] = { label: "R", data: [] };
+ $W.data[1] = { label: "G", data: [] };
+ $W.data[2] = { label: "B", data: [] };
} else if ($W.mode == "combined") {
- $W.data[0] = {label: "Combined",data:[]}
- $W.data[1] = {label: "R",data:[]}
- $W.data[2] = {label: "G",data:[]}
- $W.data[3] = {label: "B",data:[]}
- $W.data[4] = {label: "Overexposed",data:[]}
+ $W.data[0] = { label: "Combined", data: [] };
+ $W.data[1] = { label: "R", data: [] };
+ $W.data[2] = { label: "G", data: [] };
+ $W.data[3] = { label: "B", data: [] };
+ $W.data[4] = { label: "Overexposed", data: [] };
}
// store it in the "raw" data store too
- $W.full_data = []
+ $W.full_data = [];
for (var col = 0; col < $W.canvas.width; col++) {
- var red = 0
- for (row=0;row<$W.sample_height;row++) {
- red += img.data[((row*(img.width*4)) + (col*4)) + 0]
+ var red = 0;
+ for (row = 0; row < $W.sample_height; row++) {
+ red += img.data[row * (img.width * 4) + col * 4 + 0];
}
- red /= $W.sample_height
- var green = 0
- for (row=0;row<$W.sample_height;row++) {
- green += img.data[((row*(img.width*4)) + (col*4)) + 1]
+ red /= $W.sample_height;
+ var green = 0;
+ for (row = 0; row < $W.sample_height; row++) {
+ green += img.data[row * (img.width * 4) + col * 4 + 1];
}
- green /= $W.sample_height
- var blue = 0
- for (row=0;row<$W.sample_height;row++) {
- blue += img.data[((row*(img.width*4)) + (col*4)) + 2]
+ green /= $W.sample_height;
+ var blue = 0;
+ for (row = 0; row < $W.sample_height; row++) {
+ blue += img.data[row * (img.width * 4) + col * 4 + 2];
}
- blue /= $W.sample_height
- var intensity = (red+blue+green)/3
- $W.full_data.push([red,green,blue,intensity])
+ blue /= $W.sample_height;
+ var intensity = (red + blue + green) / 3;
+ $W.full_data.push([red, green, blue, intensity]);
if (!$W.calibrated) {
if ($W.mode == "average") {
- $W.data[0].data.push([col,intensity/2.55])
+ $W.data[0].data.push([col, intensity / 2.55]);
} else if ($W.mode == "rgb") {
- $W.data[0].data.push([col,red/2.55])
- $W.data[1].data.push([col,green/2.55])
- $W.data[2].data.push([col,blue/2.55])
+ $W.data[0].data.push([col, red / 2.55]);
+ $W.data[1].data.push([col, green / 2.55]);
+ $W.data[2].data.push([col, blue / 2.55]);
} else if ($W.mode == "combined") {
- $W.data[0].data.push([col,intensity/2.55])
- $W.data[1].data.push([col,red/2.55])
- $W.data[2].data.push([col,green/2.55])
- $W.data[3].data.push([col,blue/2.55])
- if (red == 255) $W.data[4].data.push([col,100])
- if (green == 255) $W.data[4].data.push([col,100])
- if (blue == 255) $W.data[4].data.push([col,100])
+ $W.data[0].data.push([col, intensity / 2.55]);
+ $W.data[1].data.push([col, red / 2.55]);
+ $W.data[2].data.push([col, green / 2.55]);
+ $W.data[3].data.push([col, blue / 2.55]);
+ if (red == 255) $W.data[4].data.push([col, 100]);
+ if (green == 255) $W.data[4].data.push([col, 100]);
+ if (blue == 255) $W.data[4].data.push([col, 100]);
}
} else {
if ($W.mode == "average") {
if ($W.baseline != null) {
- var wavelength = parseInt($W.getWavelength(col))
- $W.data[0].data.push([wavelength,$W.baseline[wavelength]-intensity/2.55])
- } else $W.data[0].data.push([parseInt($W.getWavelength(col)),intensity/2.55])
+ var wavelength = parseInt($W.getWavelength(col));
+ $W.data[0].data.push([
+ wavelength,
+ $W.baseline[wavelength] - intensity / 2.55
+ ]);
+ } else
+ $W.data[0].data.push([
+ parseInt($W.getWavelength(col)),
+ intensity / 2.55
+ ]);
} else if ($W.mode == "rgb") {
- var w = $W.getWavelength(col)
- $W.data[0].data.push([w,red/2.55])
- $W.data[1].data.push([w,green/2.55])
- $W.data[2].data.push([w,blue/2.55])
+ var w = $W.getWavelength(col);
+ $W.data[0].data.push([w, red / 2.55]);
+ $W.data[1].data.push([w, green / 2.55]);
+ $W.data[2].data.push([w, blue / 2.55]);
} else if ($W.mode == "combined") {
if ($W.baseline != null) {
- var wavelength = parseInt($W.getWavelength(col))
- $W.data[0].data.push([wavelength,$W.baseline[wavelength]-intensity/2.55])
- } else $W.data[0].data.push([parseInt($W.getWavelength(col)),intensity/2.55])
- var w = $W.getWavelength(col)
- $W.data[1].data.push([w,red/2.55])
- $W.data[2].data.push([w,green/2.55])
- $W.data[3].data.push([w,blue/2.55])
- if (red == 255) $W.data[4].data.push([w,100])
- if (green == 255) $W.data[4].data.push([w,100])
- if (blue == 255) $W.data[4].data.push([w,100])
+ var wavelength = parseInt($W.getWavelength(col));
+ $W.data[0].data.push([
+ wavelength,
+ $W.baseline[wavelength] - intensity / 2.55
+ ]);
+ } else
+ $W.data[0].data.push([
+ parseInt($W.getWavelength(col)),
+ intensity / 2.55
+ ]);
+ var w = $W.getWavelength(col);
+ $W.data[1].data.push([w, red / 2.55]);
+ $W.data[2].data.push([w, green / 2.55]);
+ $W.data[3].data.push([w, blue / 2.55]);
+ if (red == 255) $W.data[4].data.push([w, 100]);
+ if (green == 255) $W.data[4].data.push([w, 100]);
+ if (blue == 255) $W.data[4].data.push([w, 100]);
}
}
}
- $W.plot = $.plot($("#graph"),$W.data,flotoptions);
- $.each($W.markers,function(i,m) {
- $('#graph').append(''+m[0]+': '+parseInt($W.getIntensity($W.data[0].data,m[1]))+'%
');
- })
- $W.unflipped_data = $W.full_data
- if ($W.flipped) $W.unflipped_data = $W.unflipped_data.reverse()
+ $W.plot = $.plot($("#graph"), $W.data, flotoptions);
+ $.each($W.markers, function(i, m) {
+ $("#graph").append(
+ '' +
+ m[0] +
+ ": " +
+ parseInt($W.getIntensity($W.data[0].data, m[1])) +
+ "%
"
+ );
+ });
+ $W.unflipped_data = $W.full_data;
+ if ($W.flipped) $W.unflipped_data = $W.unflipped_data.reverse();
if ($W.macro && $W.macro.draw) {
try {
- $W.macro.draw()
- } catch(e) {
- console.log(e)
+ $W.macro.draw();
+ } catch (e) {
+ console.log(e);
}
}
},
geolocate: function() {
if (navigator.geolocation) {
- navigator.geolocation.getCurrentPosition($W.setGeolocation)
- return true
+ navigator.geolocation.getCurrentPosition($W.setGeolocation);
+ return true;
}
},
setGeolocation: function(loc) {
if (loc.coords) {
- $('#lat').val(loc.coords.latitude)
- $('#lon').val(loc.coords.longitude)
- }
- else {
- $('#lat').val(loc.latitude)
- $('#lon').val(loc.longitude)
+ $("#lat").val(loc.coords.latitude);
+ $("#lon").val(loc.coords.longitude);
+ } else {
+ $("#lat").val(loc.latitude);
+ $("#lon").val(loc.longitude);
}
},
saveSpectrum: function() {
var this_ = this;
- $('#dataurl').val($W.canvas.toDataURL())
- if ($('#spectrum-preview')) {
- $('#spectrum-preview')[0].src = $('#dataurl').val()
- $('#spectrum-preview').show()
+ $("#dataurl").val($W.canvas.toDataURL());
+ if ($("#spectrum-preview")) {
+ $("#spectrum-preview")[0].src = $("#dataurl").val();
+ $("#spectrum-preview").show();
}
- $('#video_row').val($W.sample_start_row)
- if ($('#geotag-toggle').length > 0) $('#geotag').val($('#geotag-toggle')[0].checked)
- setTimeout(function() { if ($('#geotag').val() == "true") $W.geolocate() },500)
+ $("#video_row").val($W.sample_start_row);
+ if ($("#geotag-toggle").length > 0)
+ $("#geotag").val($("#geotag-toggle")[0].checked);
+ setTimeout(function() {
+ if ($("#geotag").val() == "true") $W.geolocate();
+ }, 500);
this_.getRecentCalibrations("#calibration_id");
},
getRecentCalibrations: function(selector) {
$.ajax({
- url: "/capture/recent_calibrations.json?calibration_id=" + $W.calibration_id,
+ url:
+ "/capture/recent_calibrations.json?calibration_id=" + $W.calibration_id,
type: "GET",
success: function(data) {
- var html = ""
+ var html =
+ "";
$.each(data, function(index, spectrum) {
- html += "";
+ html += spectrum.created_at_in_words + " ago)";
});
$(selector).html(html);
}
- })
+ });
},
cancelSave: function() {
- $('#geotag').val('false')
- $('#lon').val('')
- $('#lat').val('')
+ $("#geotag").val("false");
+ $("#lon").val("");
+ $("#lat").val("");
},
auto_detect_sample_row: function() {
-
// We need a separate canvas to draw the snapshot, whenever we try to auto detect the sample row.
- if ($('#autoDetectCanvas').length == 0) {
- $('body').append("")
+ if ($("#autoDetectCanvas").length == 0) {
+ $("body").append(
+ ""
+ );
}
- var video = document.getElementsByTagName('video')[0]
- var canvas = document.getElementById('autoDetectCanvas')
- canvas.height = $W.height
- canvas.width = $W.width
- var context = canvas.getContext('2d')
+ var video = document.getElementsByTagName("video")[0];
+ var canvas = document.getElementById("autoDetectCanvas");
+ canvas.height = $W.height;
+ canvas.width = $W.width;
+ var context = canvas.getContext("2d");
- context.drawImage(video, 0, 0)
+ context.drawImage(video, 0, 0);
- img = context.getImageData(0,0,$W.width,$W.height)
+ img = context.getImageData(0, 0, $W.width, $W.height);
- var detected = []
- var max_avg_intensity = 0
- var selected_row = -1
+ var detected = [];
+ var max_avg_intensity = 0;
+ var selected_row = -1;
for (var row = 0; row < $W.height; row++) {
+ var red_vals = { low: 10000, high: -10000 };
+ var green_vals = { low: 10000, high: -10000 };
+ var blue_vals = { low: 10000, high: -10000 };
+ var intensity_vals = { low: 10000, high: -10000 };
+
+ var vals = [red_vals, green_vals, blue_vals, intensity_vals];
+ var sum_intensity = 0;
+ var count_intensity = 0;
+
+ for (var col = 0; col < $W.width; col++) {
+ var red = img.data[row * (img.width * 4) + col * 4 + 0];
+ var green = img.data[row * (img.width * 4) + col * 4 + 1];
+ var blue = img.data[row * (img.width * 4) + col * 4 + 2];
+ var intensity = (red + green + blue) / 3;
+
+ var bands = [red, green, blue, intensity];
+
+ $.each(vals, function(index, val) {
+ if (val["low"] > bands[index]) val["low"] = bands[index];
+ if (val["high"] < bands[index]) val["high"] = bands[index];
+ });
- var red_vals = {"low":10000, "high": -10000}
- var green_vals = {"low":10000, "high": -10000}
- var blue_vals = {"low":10000, "high": -10000}
- var intensity_vals = {"low":10000, "high": -10000}
-
- var vals = [red_vals, green_vals, blue_vals, intensity_vals]
- var sum_intensity = 0
- var count_intensity = 0
-
- for (var col = 0; col < $W.width; col++) {
- var red = img.data[((row*(img.width*4)) + (col*4)) + 0]
- var green = img.data[((row*(img.width*4)) + (col*4)) + 1]
- var blue = img.data[((row*(img.width*4)) + (col*4)) + 2]
- var intensity = (red+green+blue)/3
-
- var bands = [red, green, blue, intensity]
-
- $.each(vals, function(index, val){
- if (val["low"] > bands[index]) val["low"] = bands[index]
- if (val["high"] < bands[index]) val["high"] = bands[index]
- })
-
- sum_intensity += intensity
- count_intensity++
+ sum_intensity += intensity;
+ count_intensity++;
}
- // If we need intensity diffs,
+ // If we need intensity diffs,
// diff = intensity_vals["high"] - intensity_vals["low"]
-
- diff = red_vals["high"] - red_vals["low"]
-
+
+ diff = red_vals["high"] - red_vals["low"];
+
//console.log(diff)
if (diff > 20) {
- detected.push(row)
- var avg_intensity = parseInt(sum_intensity / count_intensity)
- if (avg_intensity < 255 && max_avg_intensity < avg_intensity){
- selected_row = row
- max_avg_intensity = avg_intensity
- }
+ detected.push(row);
+ var avg_intensity = parseInt(sum_intensity / count_intensity);
+ if (avg_intensity < 255 && max_avg_intensity < avg_intensity) {
+ selected_row = row;
+ max_avg_intensity = avg_intensity;
+ }
}
}
-
+
// console.log(selected_row)
-
+
//alert(detected)
//if (detected.length > 0) {
// $W.setSampleRows(selected_row, selected_row+1);
//}
- if (selected_row > -1) $W.setSampleRows(selected_row, selected_row+1);
- else console.log('AutoDetectSampleRow: Increase light intensity and try again!')
+ if (selected_row > -1) $W.setSampleRows(selected_row, selected_row + 1);
+ else
+ console.log(
+ "AutoDetectSampleRow: Increase light intensity and try again!"
+ );
},
// deprecate in favor of setSampleRows, or wrap it with a +1
setSampleRow: function(row) {
- $W.setSampleRows(parseInt(row),parseInt(row)+1,false)
- },
- setSampleRows: function(start,end,legacy) {
- $W.sample_start_row = start
- $W.sample_end_row = end
- localStorage.setItem('sw:samplestartrow',$W.sample_start_row)
- localStorage.setItem('sw:sampleendrow',$W.sample_end_row)
- $W.width_percent = start/$W.width
- $W.height_percent = start/$W.height
- $W.resetHeightIndicators(legacy)
- $('#video_row').val($W.sample_start_row);
+ $W.setSampleRows(parseInt(row), parseInt(row) + 1, false);
+ },
+ setSampleRows: function(start, end, legacy) {
+ $W.sample_start_row = start;
+ $W.sample_end_row = end;
+ localStorage.setItem("sw:samplestartrow", $W.sample_start_row);
+ localStorage.setItem("sw:sampleendrow", $W.sample_end_row);
+ $W.width_percent = start / $W.width;
+ $W.height_percent = start / $W.height;
+ $W.resetHeightIndicators(legacy);
+ $("#video_row").val($W.sample_start_row);
},
resetHeightIndicators: function(legacy) {
if ($W.rotated) {
- if (legacy != true) $('#heightIndicator')[0].style.marginLeft = parseInt($W.width_percent*320)+'px';
- if (legacy != true) $('#heightIndicatorPrev')[0].style.marginLeft = parseInt($W.width_percent*$('#preview').width())+'px';
+ if (legacy != true)
+ $("#heightIndicator")[0].style.marginLeft =
+ parseInt($W.width_percent * 320) + "px";
+ if (legacy != true)
+ $("#heightIndicatorPrev")[0].style.marginLeft =
+ parseInt($W.width_percent * $("#preview").width()) + "px";
} else {
- if (legacy != true) $('#heightIndicator')[0].style.marginTop = parseInt($W.height_percent*240)+'px';
- if (legacy != true) $('#heightIndicatorPrev')[0].style.marginTop = parseInt($W.height_percent*$('#preview').height())+'px';
+ if (legacy != true)
+ $("#heightIndicator")[0].style.marginTop =
+ parseInt($W.height_percent * 240) + "px";
+ if (legacy != true)
+ $("#heightIndicatorPrev")[0].style.marginTop =
+ parseInt($W.height_percent * $("#preview").height()) + "px";
}
},
setSampleRowClickListener: function() {
- $('#webcam').click(function(e){
+ $("#webcam").click(function(e) {
var offX, offY;
if (!(e.offsetX || e.offsetY)) {
offX = e.pageX - $(e.target).offset().left;
@@ -516,169 +606,187 @@ $W = {
offX = e.offsetX;
offY = e.offsetY;
}
- var percent, row
+ var percent, row;
if ($W.rotated) {
- percent = offX/$('#webcam').width()
+ percent = offX / $("#webcam").width();
if ($W.flipped) {
- row = $W.width-parseInt(percent*$W.width)
+ row = $W.width - parseInt(percent * $W.width);
} else {
- row = parseInt(percent*$W.width)
+ row = parseInt(percent * $W.width);
}
} else {
- percent = offY/$('#webcam').height()
- row = parseInt(percent*$W.height)
+ percent = offY / $("#webcam").height();
+ row = parseInt(percent * $W.height);
}
- $W.setSampleRows(row,row);
- })
+ $W.setSampleRows(row, row);
+ });
},
getWavelength: function(col) {
- return $W.start_wavelength+(col/$W.width)*($W.end_wavelength-$W.start_wavelength)
+ return (
+ $W.start_wavelength +
+ (col / $W.width) * ($W.end_wavelength - $W.start_wavelength)
+ );
},
show_rgb: function() {
- this.mode = "rgb"
- $W.oldflotoptionscolors = flotoptions.colors
- flotoptions.colors = [ "#ff0000", "#00ff00", "#0000ff" ]
- $W.plot = $.plot($("#graph"),$W.data,flotoptions);
+ this.mode = "rgb";
+ $W.oldflotoptionscolors = flotoptions.colors;
+ flotoptions.colors = ["#ff0000", "#00ff00", "#0000ff"];
+ $W.plot = $.plot($("#graph"), $W.data, flotoptions);
},
show_average: function() {
- this.mode = "average"
- $W.data = [{label: "webcam",data:[]}]
- flotoptions.colors = $W.oldflotoptionscolors
- $W.plot = $.plot($("#graph"),$W.data,flotoptions);
+ this.mode = "average";
+ $W.data = [{ label: "webcam", data: [] }];
+ flotoptions.colors = $W.oldflotoptionscolors;
+ $W.plot = $.plot($("#graph"), $W.data, flotoptions);
},
toggle_mode: function() {
- if (this.mode == "rgb") $W.show_average()
- else $W.show_rgb()
+ if (this.mode == "rgb") $W.show_average();
+ else $W.show_rgb();
},
show_combined: function() {
- this.mode = "combined"
- flotoptions.colors = [ "#ffffff", "rgba(255,0,0,0.3)", "rgba(0,255,0,0.3)", "rgba(0,0,255,0.3)", "#ffff00"]
+ this.mode = "combined";
+ flotoptions.colors = [
+ "#ffffff",
+ "rgba(255,0,0,0.3)",
+ "rgba(0,255,0,0.3)",
+ "rgba(0,0,255,0.3)",
+ "#ffff00"
+ ];
},
flip_horizontal: function() {
- $W.flipped = !$W.flipped
- if ($W.flipped == true) $('.btn-flip').addClass('active');
- else $('.btn-flip').removeClass('active');
- $('#spectrum_reversed').val($('#spectrum_reversed').val() == 'false')
- var style = $('#webcam video')[0].style
+ $W.flipped = !$W.flipped;
+ if ($W.flipped == true) $(".btn-flip").addClass("active");
+ else $(".btn-flip").removeClass("active");
+ $("#spectrum_reversed").val($("#spectrum_reversed").val() == "false");
+ var style = $("#webcam video")[0].style;
if ($W.flipped) {
- style.webkitTransform = "scaleX(-1)"
- style.mozTransform = "scaleX(-1)"
- style.oTransform = "scaleX(-1)"
- style.transform = "scaleX(-1)"
- style.filter = "FlipH"
- style.msFilter = "FlipH"
+ style.webkitTransform = "scaleX(-1)";
+ style.mozTransform = "scaleX(-1)";
+ style.oTransform = "scaleX(-1)";
+ style.transform = "scaleX(-1)";
+ style.filter = "FlipH";
+ style.msFilter = "FlipH";
} else {
- style.webkitTransform = "scaleX(1)"
- style.mozTransform = "scaleX(1)"
- style.oTransform = "scaleX(1)"
- style.transform = "scaleX(1)"
- style.filter = "none"
- style.msFilter = "none"
+ style.webkitTransform = "scaleX(1)";
+ style.mozTransform = "scaleX(1)";
+ style.oTransform = "scaleX(1)";
+ style.transform = "scaleX(1)";
+ style.filter = "none";
+ style.msFilter = "none";
}
},
toggle_rotation: function() {
- $W.rotated = !$W.rotated
- if ($W.rotated == true) $('.btn-rotate').addClass('active');
- else $('.btn-rotate').removeClass('active');
- var style = $('#heightIndicator')[0].style
- var stylePrev = $('#heightIndicatorPrev')[0].style
+ $W.rotated = !$W.rotated;
+ if ($W.rotated == true) $(".btn-rotate").addClass("active");
+ else $(".btn-rotate").removeClass("active");
+ var style = $("#heightIndicator")[0].style;
+ var stylePrev = $("#heightIndicatorPrev")[0].style;
if ($W.rotated) {
- style.marginTop = '0px';
- style.borderBottomWidth = "0px"
- style.borderRightWidth = "2px"
- style.height = "240px"
- style.width = "0px"
- stylePrev.marginTop = '0px';
- stylePrev.borderBottomWidth = "0px"
- stylePrev.borderRightWidth = "2px"
- stylePrev.height = "100px"
- stylePrev.width = "0px"
- $('#heightIndicator .vertical').show();
- $('#heightIndicator .horizontal').hide();
- $('.spectrum-example-horizontal').hide();
- $('.spectrum-example-vertical').show();
+ style.marginTop = "0px";
+ style.borderBottomWidth = "0px";
+ style.borderRightWidth = "2px";
+ style.height = "240px";
+ style.width = "0px";
+ stylePrev.marginTop = "0px";
+ stylePrev.borderBottomWidth = "0px";
+ stylePrev.borderRightWidth = "2px";
+ stylePrev.height = "100px";
+ stylePrev.width = "0px";
+ $("#heightIndicator .vertical").show();
+ $("#heightIndicator .horizontal").hide();
+ $(".spectrum-example-horizontal").hide();
+ $(".spectrum-example-vertical").show();
} else {
- style.marginLeft = '0px';
- style.borderBottomWidth = "2px"
- style.borderRightWidth = "0px"
- style.width = "320px"
- style.height = "0px"
- stylePrev.marginLeft = '0px';
- stylePrev.borderBottomWidth = "2px"
- stylePrev.borderRightWidth = "0px"
- stylePrev.width = "100%"
- stylePrev.height = "0px"
- $('#heightIndicator .vertical').hide();
- $('#heightIndicator .horizontal').show();
- $('.spectrum-example-horizontal').show();
- $('.spectrum-example-vertical').hide();
+ style.marginLeft = "0px";
+ style.borderBottomWidth = "2px";
+ style.borderRightWidth = "0px";
+ style.width = "320px";
+ style.height = "0px";
+ stylePrev.marginLeft = "0px";
+ stylePrev.borderBottomWidth = "2px";
+ stylePrev.borderRightWidth = "0px";
+ stylePrev.width = "100%";
+ stylePrev.height = "0px";
+ $("#heightIndicator .vertical").hide();
+ $("#heightIndicator .horizontal").show();
+ $(".spectrum-example-horizontal").show();
+ $(".spectrum-example-vertical").hide();
}
// reset the indicator to the correct sample row:
- $W.setSampleRows($W.sample_start_row,$W.sample_start_row)
+ $W.setSampleRows($W.sample_start_row, $W.sample_start_row);
},
is_data_ascending_in_nm: function() {
- var left_redness = 0, right_redness = 0
+ var left_redness = 0,
+ right_redness = 0;
// sum redness and unblueness for each half
// REFACTOR to read from live video
if ($W.unflipped_data.length > 0) {
- $.each($W.unflipped_data,function(index,col) {
- if (index > $W.unflipped_data.length/2) {
- left_redness += col[0]
- left_redness -= col[2]
+ $.each($W.unflipped_data, function(index, col) {
+ if (index > $W.unflipped_data.length / 2) {
+ left_redness += col[0];
+ left_redness -= col[2];
} else {
- right_redness += col[0]
- right_redness -= col[2]
+ right_redness += col[0];
+ right_redness -= col[2];
}
- })
- return (left_redness > right_redness)
+ });
+ return left_redness > right_redness;
} else {
- return true
+ return true;
}
},
markers: [],
mark: function() {
- var nm = prompt("Enter a wavelength in nanometers","532")
- var label = prompt("Enter a label","Green laser")
- var o = $W.plot.pointOffset({ x: nm, y: 90})
- if (!flotoptions.grid.markings) flotoptions.grid.markings = []
- flotoptions.grid.markings.push({ color: '#ccc', lineWidth: 1, xaxis: { from: nm, to: nm } })
- $W.plot = $.plot($("#graph"),$W.data,flotoptions);
+ var nm = prompt("Enter a wavelength in nanometers", "532");
+ var label = prompt("Enter a label", "Green laser");
+ var o = $W.plot.pointOffset({ x: nm, y: 90 });
+ if (!flotoptions.grid.markings) flotoptions.grid.markings = [];
+ flotoptions.grid.markings.push({
+ color: "#ccc",
+ lineWidth: 1,
+ xaxis: { from: nm, to: nm }
+ });
+ $W.plot = $.plot($("#graph"), $W.data, flotoptions);
- $W.markers.push([label,nm,o.left])
+ $W.markers.push([label, nm, o.left]);
},
add_spectrum: function(id) {
$.ajax({
- url: "/spectra/show/"+id+".json",
+ url: "/spectra/show/" + id + ".json",
type: "GET",
//context: document.body
success: function(result) {
- var spectrum = JSON.parse(result.data) // probably need to convert from JSON
- if ($('#baseline-toggle')[0].checked) { // use for subtracting baseline
+ var spectrum = JSON.parse(result.data); // probably need to convert from JSON
+ if ($("#baseline-toggle")[0].checked) {
+ // use for subtracting baseline
//$('#spectrum_tags').val($('#spectrum_tags').val()+",absorption")
- $W.baseline = []
- $.each(spectrum.lines,function(index,line) {
- if (line.wavelength == null) line.wavelength = index
+ $W.baseline = [];
+ $.each(spectrum.lines, function(index, line) {
+ if (line.wavelength == null) line.wavelength = index;
// quite imprecise...
- $W.baseline[parseInt(line.wavelength)] = line.average/2.55
- })
+ $W.baseline[parseInt(line.wavelength)] = line.average / 2.55;
+ });
} else {
- var label = result.spectrum.title
- $W.data.push({label:label,data:[]})
- $.each(spectrum.lines,function(index,line) {
- if (line.wavelength == null) line.wavelength = index
- $W.data[$W.data.length-1].data.push([line.wavelength,line.average/2.55])
- })
- $W.plot = $.plot($("#graph"),$W.data,flotoptions);
+ var label = result.spectrum.title;
+ $W.data.push({ label: label, data: [] });
+ $.each(spectrum.lines, function(index, line) {
+ if (line.wavelength == null) line.wavelength = index;
+ $W.data[$W.data.length - 1].data.push([
+ line.wavelength,
+ line.average / 2.55
+ ]);
+ });
+ $W.plot = $.plot($("#graph"), $W.data, flotoptions);
}
}
- })
+ });
},
overexposure_threshold: 15, // how many pixels of consecutive 100% triggers an overexposure warning
@@ -693,101 +801,112 @@ $W = {
* pixels of 100%, which would indicate overexposure. Returns
* whether it passed the threshold and the last inspected index.
*/
- overexposure_recurse: function(data,i,count,color) {
- if (count > $W.overexposure_threshold) return [true,i]
+ overexposure_recurse: function(data, i, count, color) {
+ if (count > $W.overexposure_threshold) return [true, i];
else {
- if (data[i][({r:0,g:1,b:2})[color]] >= 250) {
- return $W.overexposure_recurse(data,i+2,count+2,color)
- } else return [false,i]
+ if (data[i][{ r: 0, g: 1, b: 2 }[color]] >= 250) {
+ return $W.overexposure_recurse(data, i + 2, count + 2, color);
+ } else return [false, i];
}
},
detect_overexposure: function() {
- var overexposed = {r: false, g: false, b: false}
- var colors = ["r","g","b"]
+ var overexposed = { r: false, g: false, b: false };
+ var colors = ["r", "g", "b"];
// check each channel for plateaus at 100%:
- $.each(colors,function(index,color) {
+ $.each(colors, function(index, color) {
var i = 0;
while (i < $W.full_data.length) {
- var line = $W.full_data[i]
- var scan = $W.overexposure_recurse($W.full_data,i,0,color)
+ var line = $W.full_data[i];
+ var scan = $W.overexposure_recurse($W.full_data, i, 0, color);
if (scan[0]) {
- overexposed[color] = true
- i = $W.full_data.length
- } else i = scan[1]+10
+ overexposed[color] = true;
+ i = $W.full_data.length;
+ } else i = scan[1] + 10;
}
- })
- return overexposed
+ });
+ return overexposed;
},
// checks overexposure and displays an alert if it is so, and what channel
alert_overexposure: function() {
- console.log('Checking for overexposure');
- var oe = $W.detect_overexposure()
+ console.log("Checking for overexposure");
+ var oe = $W.detect_overexposure();
if (oe.r || oe.g || oe.b) {
- var msg = "Light source too strong; clipping in channels: "
- var channels = []
- if (oe.r) channels.push("red")
- if (oe.g) channels.push("green")
- if (oe.b) channels.push("blue")
- $W.notify(msg+channels.join(', '),"warning")
+ var msg = "Light source too strong; clipping in channels: ";
+ var channels = [];
+ if (oe.r) channels.push("red");
+ if (oe.g) channels.push("green");
+ if (oe.b) channels.push("blue");
+ $W.notify(msg + channels.join(", "), "warning");
// notify is not working in capture, not sure why...
- $('.capture-navbar .capture-messages').html(msg + channels.join(', '));
- $('.capture-navbar').addClass('red');
+ $(".capture-navbar .capture-messages").html(msg + channels.join(", "));
+ $(".capture-navbar").addClass("red");
} else {
- $('.capture-navbar .capture-messages').html('');
- $('.capture-navbar').removeClass('red');
+ $(".capture-navbar .capture-messages").html("");
+ $(".capture-navbar").removeClass("red");
}
},
//setTimeout($W.alert_overexposure,3000)
- notify: function(msg,type,expire) {
- if (expire == null) expire = true
- var id = parseInt(Math.random()*100000)
- $('#notify').html($('#notify').html()+"")
- if (type == "warning") $('#notify_'+id).html("Warning: "+msg).addClass('warning')
- if (type == "error") $('#notify_'+id).html("Error: "+msg).addClass('error')
+ notify: function(msg, type, expire) {
+ if (expire == null) expire = true;
+ var id = parseInt(Math.random() * 100000);
+ $("#notify").html(
+ $("#notify").html() + ""
+ );
+ if (type == "warning")
+ $("#notify_" + id)
+ .html("Warning: " + msg)
+ .addClass("warning");
+ if (type == "error")
+ $("#notify_" + id)
+ .html("Error: " + msg)
+ .addClass("error");
if (expire) {
setTimeout(function() {
- $('#notify_'+id).remove()
- },2000)
+ $("#notify_" + id).remove();
+ }, 2000);
}
},
- getIntensity: function(data,x) {
- var i, j
+ getIntensity: function(data, x) {
+ var i, j;
// find the nearest points, x-wise
- for (j = 0; j < data.length; ++j)
- if (data[j][0] > x)
- break;
+ for (j = 0; j < data.length; ++j) if (data[j][0] > x) break;
// now interpolate
- var y, p1 = data[j - 1], p2 = data[j];
- if (p1 == null)
- y = p2[1];
- else if (p2 == null)
- y = p1[1];
- else
- y = p1[1] + (p2[1] - p1[1]) * (x - p1[0]) / (p2[0] - p1[0]);
+ var y,
+ p1 = data[j - 1],
+ p2 = data[j];
+ if (p1 == null) y = p2[1];
+ else if (p2 == null) y = p1[1];
+ else y = p1[1] + ((p2[1] - p1[1]) * (x - p1[0])) / (p2[0] - p1[0]);
- return y
+ return y;
},
/**
- * Returns a canvas object of any rect from the offered canvas
- */
- excerptCanvas: function(x1,y1,x2,y2,source) {
- source = source || $W.canvas
- var width = x2-x1, height = y2-y1
- if ($('#excerptCanvas').length == 0) {
- $('body').append("")
+ * Returns a canvas object of any rect from the offered canvas
+ */
+ excerptCanvas: function(x1, y1, x2, y2, source) {
+ source = source || $W.canvas;
+ var width = x2 - x1,
+ height = y2 - y1;
+ if ($("#excerptCanvas").length == 0) {
+ $("body").append(
+ ""
+ );
}
- var element = $('#excerptCanvas')[0]
- element.width = width
- element.height = height
- var excerptCanvasContext = element.getContext('2d')
- var sourcedata = source.getImageData(x1,y1,width,height)
- excerptCanvasContext.putImageData(sourcedata,0,0)
- return excerptCanvasContext
+ var element = $("#excerptCanvas")[0];
+ element.width = width;
+ element.height = height;
+ var excerptCanvasContext = element.getContext("2d");
+ var sourcedata = source.getImageData(x1, y1, width, height);
+ excerptCanvasContext.putImageData(sourcedata, 0, 0);
+ return excerptCanvasContext;
}
-
+};
+function getVideoEl() {
+ if ($W.loadingfromPi) return $W.piImage;
+ else return $("video")[0];
}
diff --git a/examples/capture/index.html b/examples/capture/index.html
index e0f1c06e..38f5ae2d 100644
--- a/examples/capture/index.html
+++ b/examples/capture/index.html
@@ -24,8 +24,10 @@
+
+
+ Connect to Raspberry-Pi
-
-
+
Begin capturing »
@@ -345,17 +348,31 @@ Macros
width: 640
})
-
setInterval($W.getRow,100)
$W.calibrated = false
if ($('body').width() > 768) $('#tool-toggle').hide()
else $('#tool-pane').hide()
-
- })();
+ })();
+
+//code to connect to raspberry-pi
+ var el=document.getElementById("pi-button");
+ if(el){
+ //if pi_div button does not return null
+document.getElementById("pi-button").addEventListener("click", function connect_to_pi() {
+ $W.loadingfromPi=true;
+ $W.piImage = new Image();
+ $W.piImage.onload = function () {
+ var sourceX = 0, sourceY = 0, sourceHeight = 300, sourceWidth = 800;
+ $W.ctx.drawImage($W.piImage, sourceX, sourceY, sourceHeight, sourceWidth, 0, 0, $W.width, 1);
+ };
+ var fetchImageInterval = setInterval(function fetchImage() {
+ // piImage.src = "http://pi.local/cam/cam_pic.php?time=" + new Date().getTime();
+ $W.piImage.src = "../logo.png";//demo picture
+ }, 50);
+ });
+}
-
-
-