jpeg_camera 1.0.2 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -2
- data/vendor/assets/images/jpeg_camera/jpeg_camera.swf +0 -0
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera.js +259 -58
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera.min.js +2 -2
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera_no_flash.js +203 -49
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera_no_flash.min.js +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a7c6193f58611135096435b910e2e8993c3b9e2
|
4
|
+
data.tar.gz: c7b3cefe427aad352edb709cbb69c7ad68e6af8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c5bf844429a15859fdee5e5cbce30109d675887a22a00271e2fbe69b60a854897cf8458b023bc4ace060efe8776ac969081ca895c2020f532608d67c6f53298
|
7
|
+
data.tar.gz: 344a2fc9f83f7447379e52a65f0c9b595983a1e9cc675b6ec7f70433ac53c9842dfc108766fb81780439053eaeeda89bd05083218d7a730fdb8c4820b0adda1f
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
## About
|
2
2
|
|
3
|
-
JpegCamera is a JavaScript library that allows you display a camera stream on
|
3
|
+
JpegCamera is a JavaScript library that allows you to display a camera stream on
|
4
4
|
a web page and then capture, show and upload JPEG snapshots to the server. It
|
5
5
|
uses HTML5 in Chrome, Firefox and Opera and falls back to Flash in less capable
|
6
6
|
browsers. The video stream is placed without any UI in a container of your
|
@@ -18,10 +18,20 @@ has some nice, new features.
|
|
18
18
|
- Manage and upload multiple snapshots at once. You don't have to wait for the
|
19
19
|
first upload to finish before capturing the next image. This means you can
|
20
20
|
take a few shots in a short interval.
|
21
|
+
- You can get snapshots for display outside the camera container in browsers
|
22
|
+
that support `canvas` element - even when using Flash fallback.
|
21
23
|
- Allows you to retry failed uploads.
|
22
24
|
- Easily read server response text and code after upload.
|
23
25
|
- Send CSRF tokens to secure your user's session from [Cross-site request
|
24
26
|
forgery](http://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention)
|
27
|
+
- Prevents users from messing with HTML5 VIDEO or Flash object elements
|
28
|
+
by overlaying transparent DIV over them after initialization.
|
29
|
+
- Makes sure the camera is really ready by checking stream's color standard
|
30
|
+
deviation. Safeguard from weird all-black or all-white snapshots.
|
31
|
+
|
32
|
+
## Demo
|
33
|
+
|
34
|
+
Check out the [demo page](http://amw.github.io/jpeg_camera/demo/).
|
25
35
|
|
26
36
|
## Dependencies
|
27
37
|
|
@@ -64,7 +74,7 @@ to also load Canvas-to-Blob. You don't need SWFObject for HTML5.
|
|
64
74
|
|
65
75
|
Require the gem in your Gemfile.
|
66
76
|
|
67
|
-
gem "jpeg_camera", "~> 1.
|
77
|
+
gem "jpeg_camera", "~> 1.1.1"
|
68
78
|
|
69
79
|
Add appropriate requires to your application.js. SWFObject and Canvas-to-Blob
|
70
80
|
are stored in separate files so that you don't have to load them again if you
|
@@ -115,6 +125,10 @@ that finish with status codes from outside the 2XX range (like 404 Not Found or
|
|
115
125
|
fallback your application should not rely on reading body of these responses.
|
116
126
|
The status code number is always available.
|
117
127
|
|
128
|
+
Current stable versions of Firefox and Opera support getUserMedia, but do not
|
129
|
+
support Web Audio API. I have decided against loading a Flash object in
|
130
|
+
these browsers so JpegCamera will be silent.
|
131
|
+
|
118
132
|
## Contributing
|
119
133
|
|
120
134
|
The source code is available on [Github](https://github.com/amw/jpeg_camera).
|
Binary file
|
@@ -1,8 +1,8 @@
|
|
1
|
-
/*! JpegCamera 1.
|
1
|
+
/*! JpegCamera 1.1.1 | 2013-08-05
|
2
2
|
(c) 2013 Adam Wrobel
|
3
3
|
http://amw.github.io/jpeg_camera */
|
4
4
|
(function() {
|
5
|
-
var JpegCamera, JpegCameraFlash, JpegCameraHtml5, Snapshot, supported_flash_version, _ref, _ref1,
|
5
|
+
var JpegCamera, JpegCameraFlash, JpegCameraHtml5, Snapshot, check_canvas_to_blob, supported_flash_version, _ref, _ref1,
|
6
6
|
__hasProp = {}.hasOwnProperty,
|
7
7
|
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
8
8
|
|
@@ -22,16 +22,25 @@
|
|
22
22
|
retry_success: false
|
23
23
|
};
|
24
24
|
|
25
|
+
JpegCamera._canvas_supported = !!document.createElement('canvas').getContext;
|
26
|
+
|
27
|
+
JpegCamera.canvas_supported = function() {
|
28
|
+
return this._canvas_supported;
|
29
|
+
};
|
30
|
+
|
25
31
|
function JpegCamera(container, options) {
|
26
32
|
if ("string" === typeof container) {
|
27
|
-
|
28
|
-
} else {
|
29
|
-
this.container = container;
|
33
|
+
container = document.getElementById(container.replace("#", ""));
|
30
34
|
}
|
31
|
-
if (!(
|
35
|
+
if (!(container && container.offsetWidth)) {
|
32
36
|
throw "JpegCamera: invalid container";
|
33
37
|
}
|
34
|
-
|
38
|
+
container.innerHTML = "";
|
39
|
+
this.container = document.createElement("div");
|
40
|
+
this.container.style.width = "100%";
|
41
|
+
this.container.style.height = "100%";
|
42
|
+
this.container.style.position = "relative";
|
43
|
+
container.appendChild(this.container);
|
35
44
|
this.options = this._extend({}, this.constructor.DefaultOptions, options);
|
36
45
|
this._engine_init();
|
37
46
|
}
|
@@ -56,6 +65,18 @@
|
|
56
65
|
|
57
66
|
JpegCamera.prototype._error_occured = false;
|
58
67
|
|
68
|
+
JpegCamera.StatsCaptureScale = 0.2;
|
69
|
+
|
70
|
+
JpegCamera.prototype.get_stats = function(callback) {
|
71
|
+
var snapshot, that;
|
72
|
+
snapshot = new Snapshot(this, {});
|
73
|
+
this._engine_capture(snapshot, false, 0.1, JpegCamera.StatsCaptureScale);
|
74
|
+
that = this;
|
75
|
+
return snapshot.get_stats(function(stats) {
|
76
|
+
return callback.call(that, stats);
|
77
|
+
});
|
78
|
+
};
|
79
|
+
|
59
80
|
JpegCamera.prototype.capture = function(options) {
|
60
81
|
var snapshot, _options;
|
61
82
|
if (options == null) {
|
@@ -67,7 +88,7 @@
|
|
67
88
|
if (_options.shutter) {
|
68
89
|
this._engine_play_shutter_sound();
|
69
90
|
}
|
70
|
-
this._engine_capture(snapshot, _options.mirror, _options.quality);
|
91
|
+
this._engine_capture(snapshot, _options.mirror, _options.quality, 1.0);
|
71
92
|
return snapshot;
|
72
93
|
};
|
73
94
|
|
@@ -130,10 +151,6 @@
|
|
130
151
|
|
131
152
|
JpegCamera.prototype._displayed_snapshot = null;
|
132
153
|
|
133
|
-
JpegCamera.prototype._upload = function(snapshot, api_url, csrf_token, timeout) {
|
134
|
-
return this._engine_upload(snapshot, api_url, csrf_token, timeout);
|
135
|
-
};
|
136
|
-
|
137
154
|
JpegCamera.prototype._discard = function(snapshot) {
|
138
155
|
if (this._displayed_snapshot === snapshot) {
|
139
156
|
this.show_stream();
|
@@ -144,10 +161,33 @@
|
|
144
161
|
};
|
145
162
|
|
146
163
|
JpegCamera.prototype._prepared = function() {
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
164
|
+
var that;
|
165
|
+
that = this;
|
166
|
+
return setTimeout((function() {
|
167
|
+
return that._wait_until_stream_looks_ok(true);
|
168
|
+
}), 1);
|
169
|
+
};
|
170
|
+
|
171
|
+
JpegCamera.prototype._wait_until_stream_looks_ok = function(show_debug) {
|
172
|
+
return this.get_stats(function(stats) {
|
173
|
+
var that;
|
174
|
+
if (stats.std > 2) {
|
175
|
+
this._debug("Stream mean gray value = " + stats.mean + " standard deviation = " + stats.std);
|
176
|
+
this._debug("Camera is ready");
|
177
|
+
this._is_ready = true;
|
178
|
+
if (this.options.on_ready) {
|
179
|
+
return this.options.on_ready.call(this);
|
180
|
+
}
|
181
|
+
} else {
|
182
|
+
if (show_debug) {
|
183
|
+
this._debug("Stream mean gray value = " + stats.mean + " standard deviation = " + stats.std);
|
184
|
+
}
|
185
|
+
that = this;
|
186
|
+
return setTimeout((function() {
|
187
|
+
return that._wait_until_stream_looks_ok(false);
|
188
|
+
}), 100);
|
189
|
+
}
|
190
|
+
});
|
151
191
|
};
|
152
192
|
|
153
193
|
JpegCamera.prototype._got_error = function(error) {
|
@@ -158,13 +198,45 @@
|
|
158
198
|
}
|
159
199
|
};
|
160
200
|
|
201
|
+
JpegCamera.prototype._block_element_access = function() {
|
202
|
+
this._overlay = document.createElement("div");
|
203
|
+
this._overlay.style.width = "100%";
|
204
|
+
this._overlay.style.height = "100%";
|
205
|
+
this._overlay.style.position = "absolute";
|
206
|
+
this._overlay.style.top = 0;
|
207
|
+
this._overlay.style.left = 0;
|
208
|
+
this._overlay.style.zIndex = 2;
|
209
|
+
return this.container.appendChild(this._overlay);
|
210
|
+
};
|
211
|
+
|
212
|
+
JpegCamera.prototype._overlay = null;
|
213
|
+
|
214
|
+
JpegCamera._add_prefixed_style = function(element, style, value) {
|
215
|
+
var uppercase_style;
|
216
|
+
uppercase_style = style.charAt(0).toUpperCase() + style.slice(1);
|
217
|
+
element.style[style] = value;
|
218
|
+
element.style["Webkit" + uppercase_style] = value;
|
219
|
+
element.style["Moz" + uppercase_style] = value;
|
220
|
+
element.style["ms" + uppercase_style] = value;
|
221
|
+
return element.style["O" + uppercase_style] = value;
|
222
|
+
};
|
223
|
+
|
161
224
|
return JpegCamera;
|
162
225
|
|
163
226
|
})();
|
164
227
|
|
165
228
|
navigator.getUserMedia || (navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
|
166
229
|
|
230
|
+
check_canvas_to_blob = function() {
|
231
|
+
var canvas;
|
232
|
+
canvas = document.createElement("canvas");
|
233
|
+
if (canvas.getContext && !canvas.toBlob) {
|
234
|
+
throw "JpegCamera: Canvas-to-Blob is not loaded";
|
235
|
+
}
|
236
|
+
};
|
237
|
+
|
167
238
|
if (navigator.getUserMedia) {
|
239
|
+
check_canvas_to_blob();
|
168
240
|
JpegCameraHtml5 = (function(_super) {
|
169
241
|
__extends(JpegCameraHtml5, _super);
|
170
242
|
|
@@ -174,20 +246,15 @@
|
|
174
246
|
}
|
175
247
|
|
176
248
|
JpegCameraHtml5.prototype._engine_init = function() {
|
177
|
-
var get_user_media_options, horizontal_padding, that, vertical_padding;
|
249
|
+
var error, failure, get_user_media_options, horizontal_padding, success, that, vertical_padding;
|
178
250
|
this._debug("Using HTML5 engine");
|
179
|
-
this.internal_container = document.createElement("div");
|
180
|
-
this.internal_container.style.width = "100%";
|
181
|
-
this.internal_container.style.height = "100%";
|
182
|
-
this.internal_container.style.position = "relative";
|
183
|
-
this.container.appendChild(this.internal_container);
|
184
251
|
vertical_padding = Math.floor(this._view_height() * 0.2);
|
185
252
|
horizontal_padding = Math.floor(this._view_width() * 0.2);
|
186
253
|
this.message = document.createElement("div");
|
187
254
|
this.message["class"] = "message";
|
188
255
|
this.message.style.width = "100%";
|
189
256
|
this.message.style.height = "100%";
|
190
|
-
|
257
|
+
JpegCamera._add_prefixed_style(this.message, "boxSizing", "border-box");
|
191
258
|
this.message.style.overflow = "hidden";
|
192
259
|
this.message.style.textAlign = "center";
|
193
260
|
this.message.style.paddingTop = "" + vertical_padding + "px";
|
@@ -196,18 +263,18 @@
|
|
196
263
|
this.message.style.paddingRight = "" + horizontal_padding + "px";
|
197
264
|
this.message.style.position = "absolute";
|
198
265
|
this.message.style.zIndex = 3;
|
199
|
-
this.message.innerHTML = "Please allow camera access when prompted by the browser.";
|
200
|
-
this.
|
266
|
+
this.message.innerHTML = "Please allow camera access when prompted by the browser.<br><br>" + "Look for camera icon around your address bar.";
|
267
|
+
this.container.appendChild(this.message);
|
201
268
|
this.video_container = document.createElement("div");
|
202
269
|
this.video_container.style.width = "" + (this._view_width()) + "px";
|
203
270
|
this.video_container.style.height = "" + (this._view_height()) + "px";
|
204
271
|
this.video_container.style.overflow = "hidden";
|
205
272
|
this.video_container.style.position = "absolute";
|
206
273
|
this.video_container.style.zIndex = 1;
|
207
|
-
this.
|
274
|
+
this.container.appendChild(this.video_container);
|
208
275
|
this.video = document.createElement('video');
|
209
276
|
this.video.autoplay = true;
|
210
|
-
|
277
|
+
JpegCamera._add_prefixed_style(this.video, "transform", "scalex(-1.0)");
|
211
278
|
window.AudioContext || (window.AudioContext = window.webkitAudioContext);
|
212
279
|
if (window.AudioContext) {
|
213
280
|
this._load_shutter_sound();
|
@@ -228,16 +295,19 @@
|
|
228
295
|
}
|
229
296
|
};
|
230
297
|
that = this;
|
231
|
-
|
298
|
+
success = function(stream) {
|
232
299
|
that._remove_message();
|
233
300
|
if (window.URL) {
|
234
301
|
that.video.src = URL.createObjectURL(stream);
|
235
302
|
} else {
|
236
303
|
that.video.src = stream;
|
237
304
|
}
|
305
|
+
that._block_element_access();
|
238
306
|
return that._wait_for_video_ready();
|
239
|
-
}
|
307
|
+
};
|
308
|
+
failure = function(error) {
|
240
309
|
var code, key, value;
|
310
|
+
that.message.innerHTML = "<span style=\"color: red;\">" + "You have denied camera access." + "</span><br><br>" + "Look for camera icon around your address bar to change your " + "decision.";
|
241
311
|
code = error.code;
|
242
312
|
for (key in error) {
|
243
313
|
value = error[key];
|
@@ -248,7 +318,13 @@
|
|
248
318
|
return;
|
249
319
|
}
|
250
320
|
return that._got_error("UNKNOWN ERROR");
|
251
|
-
}
|
321
|
+
};
|
322
|
+
try {
|
323
|
+
return navigator.getUserMedia(get_user_media_options, success, failure);
|
324
|
+
} catch (_error) {
|
325
|
+
error = _error;
|
326
|
+
return navigator.getUserMedia("video", success, failure);
|
327
|
+
}
|
252
328
|
};
|
253
329
|
|
254
330
|
JpegCameraHtml5.prototype._engine_play_shutter_sound = function() {
|
@@ -262,14 +338,14 @@
|
|
262
338
|
return source.start(0);
|
263
339
|
};
|
264
340
|
|
265
|
-
JpegCameraHtml5.prototype._engine_capture = function(snapshot, mirror, quality) {
|
341
|
+
JpegCameraHtml5.prototype._engine_capture = function(snapshot, mirror, quality, scale) {
|
266
342
|
var canvas, context, crop;
|
267
343
|
crop = this._get_capture_crop();
|
268
344
|
canvas = document.createElement("canvas");
|
269
|
-
canvas.width = crop.width;
|
270
|
-
canvas.height = crop.height;
|
345
|
+
canvas.width = Math.round(crop.width * scale);
|
346
|
+
canvas.height = Math.round(crop.height * scale);
|
271
347
|
context = canvas.getContext("2d");
|
272
|
-
context.drawImage(this.video, crop.x_offset, crop.y_offset, crop.width, crop.height, 0, 0, crop.width, crop.height);
|
348
|
+
context.drawImage(this.video, crop.x_offset, crop.y_offset, crop.width, crop.height, 0, 0, Math.round(crop.width * scale), Math.round(crop.height * scale));
|
273
349
|
snapshot._canvas = canvas;
|
274
350
|
snapshot._mirror = mirror;
|
275
351
|
return snapshot._quality = quality;
|
@@ -277,7 +353,7 @@
|
|
277
353
|
|
278
354
|
JpegCameraHtml5.prototype._engine_display = function(snapshot) {
|
279
355
|
if (this.displayed_canvas) {
|
280
|
-
this.
|
356
|
+
this.container.removeChild(this.displayed_canvas);
|
281
357
|
}
|
282
358
|
this.displayed_canvas = snapshot._canvas;
|
283
359
|
this.displayed_canvas.style.width = "" + (this._view_width()) + "px";
|
@@ -286,8 +362,25 @@
|
|
286
362
|
this.displayed_canvas.style.left = 0;
|
287
363
|
this.displayed_canvas.style.position = "absolute";
|
288
364
|
this.displayed_canvas.style.zIndex = 2;
|
289
|
-
|
290
|
-
return this.
|
365
|
+
JpegCamera._add_prefixed_style(this.displayed_canvas, "transform", "scalex(-1.0)");
|
366
|
+
return this.container.appendChild(this.displayed_canvas);
|
367
|
+
};
|
368
|
+
|
369
|
+
JpegCameraHtml5.prototype._engine_get_canvas = function(snapshot) {
|
370
|
+
var canvas, context;
|
371
|
+
canvas = document.createElement("canvas");
|
372
|
+
canvas.width = snapshot._canvas.width;
|
373
|
+
canvas.height = snapshot._canvas.height;
|
374
|
+
context = canvas.getContext("2d");
|
375
|
+
context.drawImage(snapshot._canvas, 0, 0);
|
376
|
+
return canvas;
|
377
|
+
};
|
378
|
+
|
379
|
+
JpegCameraHtml5.prototype._engine_get_image_data = function(snapshot) {
|
380
|
+
var canvas, context;
|
381
|
+
canvas = snapshot._canvas;
|
382
|
+
context = canvas.getContext("2d");
|
383
|
+
return context.getImageData(0, 0, canvas.width, canvas.height);
|
291
384
|
};
|
292
385
|
|
293
386
|
JpegCameraHtml5.prototype._engine_discard = function(snapshot) {
|
@@ -301,7 +394,7 @@
|
|
301
394
|
|
302
395
|
JpegCameraHtml5.prototype._engine_show_stream = function() {
|
303
396
|
if (this.displayed_canvas) {
|
304
|
-
this.
|
397
|
+
this.container.removeChild(this.displayed_canvas);
|
305
398
|
this.displayed_canvas = null;
|
306
399
|
}
|
307
400
|
return this.video_container.style.display = "block";
|
@@ -406,16 +499,6 @@
|
|
406
499
|
|
407
500
|
JpegCameraHtml5.prototype._status_checks_count = 0;
|
408
501
|
|
409
|
-
JpegCameraHtml5.prototype._add_prefixed_style = function(element, style, value) {
|
410
|
-
var uppercase_style;
|
411
|
-
uppercase_style = style.charAt(0).toUpperCase() + style.slice(1);
|
412
|
-
element.style[style] = value;
|
413
|
-
element.style["Webkit" + uppercase_style] = value;
|
414
|
-
element.style["Moz" + uppercase_style] = value;
|
415
|
-
element.style["ms" + uppercase_style] = value;
|
416
|
-
return element.style["O" + uppercase_style] = value;
|
417
|
-
};
|
418
|
-
|
419
502
|
JpegCameraHtml5.prototype._get_video_crop = function() {
|
420
503
|
var scaled_video_height, scaled_video_width, video_ratio, video_scale, view_height, view_ratio, view_width;
|
421
504
|
view_width = this._view_width();
|
@@ -482,6 +565,10 @@
|
|
482
565
|
|
483
566
|
supported_flash_version = '9';
|
484
567
|
|
568
|
+
if (!window.swfobject) {
|
569
|
+
throw "JpegCamera: SWFObject is not loaded";
|
570
|
+
}
|
571
|
+
|
485
572
|
if (!window.JpegCamera && window.swfobject && swfobject.hasFlashPlayerVersion(supported_flash_version)) {
|
486
573
|
JpegCameraFlash = (function(_super) {
|
487
574
|
__extends(JpegCameraFlash, _super);
|
@@ -506,7 +593,7 @@
|
|
506
593
|
JpegCameraFlash._next_id = 1;
|
507
594
|
|
508
595
|
JpegCameraFlash.prototype._engine_init = function() {
|
509
|
-
var attributes, callback, flash_object_id, flashvars, height, params, that, width;
|
596
|
+
var attributes, callback, container_to_be_replaced, flash_object_id, flashvars, height, params, that, width;
|
510
597
|
this._debug("Using Flash engine");
|
511
598
|
this._id = this.constructor._next_id++;
|
512
599
|
this.constructor._instances[this._id] = this;
|
@@ -544,26 +631,68 @@
|
|
544
631
|
return that._flash = document.getElementById(flash_object_id);
|
545
632
|
}
|
546
633
|
};
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
this.container.appendChild(
|
552
|
-
return swfobject.embedSWF(this.options.swf_url,
|
634
|
+
container_to_be_replaced = document.createElement("div");
|
635
|
+
container_to_be_replaced.id = "jpeg_camera_flash_" + this._id;
|
636
|
+
container_to_be_replaced.style.width = "100%";
|
637
|
+
container_to_be_replaced.style.height = "100%";
|
638
|
+
this.container.appendChild(container_to_be_replaced);
|
639
|
+
return swfobject.embedSWF(this.options.swf_url, container_to_be_replaced.id, width, height, '9', null, flashvars, params, attributes, callback);
|
553
640
|
};
|
554
641
|
|
555
642
|
JpegCameraFlash.prototype._engine_play_shutter_sound = function() {
|
556
643
|
return this._flash._play_shutter();
|
557
644
|
};
|
558
645
|
|
559
|
-
JpegCameraFlash.prototype._engine_capture = function(snapshot, mirror, quality) {
|
560
|
-
return this._flash._capture(snapshot.id, mirror, quality);
|
646
|
+
JpegCameraFlash.prototype._engine_capture = function(snapshot, mirror, quality, scale) {
|
647
|
+
return this._flash._capture(snapshot.id, mirror, quality, scale);
|
561
648
|
};
|
562
649
|
|
563
650
|
JpegCameraFlash.prototype._engine_display = function(snapshot) {
|
564
651
|
return this._flash._display(snapshot.id);
|
565
652
|
};
|
566
653
|
|
654
|
+
JpegCameraFlash.prototype._engine_get_canvas = function(snapshot) {
|
655
|
+
var canvas, context;
|
656
|
+
snapshot._image_data || (snapshot._image_data = this._engine_get_image_data(snapshot));
|
657
|
+
canvas = document.createElement("canvas");
|
658
|
+
canvas.width = snapshot._image_data.width;
|
659
|
+
canvas.height = snapshot._image_data.height;
|
660
|
+
context = canvas.getContext("2d");
|
661
|
+
context.putImageData(snapshot._image_data, 0, 0);
|
662
|
+
return canvas;
|
663
|
+
};
|
664
|
+
|
665
|
+
JpegCameraFlash.prototype._engine_get_image_data = function(snapshot) {
|
666
|
+
var blue, canvas, context, flash_data, green, i, index, pixel, red, result, _i, _len, _ref2;
|
667
|
+
flash_data = this._flash._get_image_data(snapshot.id);
|
668
|
+
if (JpegCamera.canvas_supported()) {
|
669
|
+
canvas = document.createElement("canvas");
|
670
|
+
canvas.width = flash_data.width;
|
671
|
+
canvas.height = flash_data.height;
|
672
|
+
context = canvas.getContext("2d");
|
673
|
+
result = context.createImageData(flash_data.width, flash_data.height);
|
674
|
+
} else {
|
675
|
+
result = {
|
676
|
+
data: [],
|
677
|
+
width: flash_data.width,
|
678
|
+
height: flash_data.height
|
679
|
+
};
|
680
|
+
}
|
681
|
+
_ref2 = flash_data.data;
|
682
|
+
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
|
683
|
+
pixel = _ref2[i];
|
684
|
+
index = i * 4;
|
685
|
+
red = pixel >> 16 & 0xff;
|
686
|
+
green = pixel >> 8 & 0xff;
|
687
|
+
blue = pixel & 0xff;
|
688
|
+
result.data[index + 0] = red;
|
689
|
+
result.data[index + 1] = green;
|
690
|
+
result.data[index + 2] = blue;
|
691
|
+
result.data[index + 3] = 255;
|
692
|
+
}
|
693
|
+
return result;
|
694
|
+
};
|
695
|
+
|
567
696
|
JpegCameraFlash.prototype._engine_discard = function(snapshot) {
|
568
697
|
return this._flash._discard(snapshot.id);
|
569
698
|
};
|
@@ -577,6 +706,7 @@
|
|
577
706
|
};
|
578
707
|
|
579
708
|
JpegCameraFlash.prototype._flash_prepared = function() {
|
709
|
+
this._block_element_access();
|
580
710
|
return this._prepared();
|
581
711
|
};
|
582
712
|
|
@@ -626,6 +756,48 @@
|
|
626
756
|
return this;
|
627
757
|
};
|
628
758
|
|
759
|
+
Snapshot.prototype.get_stats = function(callback) {
|
760
|
+
if (this._discarded) {
|
761
|
+
raise("discarded snapshot cannot be used");
|
762
|
+
}
|
763
|
+
return this.get_image_data(function(data) {
|
764
|
+
return this._get_stats(data, callback);
|
765
|
+
});
|
766
|
+
};
|
767
|
+
|
768
|
+
Snapshot.prototype.get_canvas = function(callback) {
|
769
|
+
var that;
|
770
|
+
if (this._discarded) {
|
771
|
+
raise("discarded snapshot cannot be used");
|
772
|
+
}
|
773
|
+
if (!JpegCamera._canvas_supported) {
|
774
|
+
false;
|
775
|
+
}
|
776
|
+
that = this;
|
777
|
+
setTimeout(function() {
|
778
|
+
that._extra_canvas || (that._extra_canvas = that.camera._engine_get_canvas(that));
|
779
|
+
JpegCamera._add_prefixed_style(that._extra_canvas, "transform", "scalex(-1.0)");
|
780
|
+
return callback.call(that, that._extra_canvas);
|
781
|
+
}, 10);
|
782
|
+
return true;
|
783
|
+
};
|
784
|
+
|
785
|
+
Snapshot.prototype._extra_canvas = null;
|
786
|
+
|
787
|
+
Snapshot.prototype.get_image_data = function(callback) {
|
788
|
+
var that;
|
789
|
+
if (this._discarded) {
|
790
|
+
raise("discarded snapshot cannot be used");
|
791
|
+
}
|
792
|
+
that = this;
|
793
|
+
return setTimeout(function() {
|
794
|
+
that._image_data || (that._image_data = that.camera._engine_get_image_data(that));
|
795
|
+
return callback.call(that, that._image_data);
|
796
|
+
}, 5);
|
797
|
+
};
|
798
|
+
|
799
|
+
Snapshot.prototype._image_data = null;
|
800
|
+
|
629
801
|
Snapshot.prototype.upload = function(options) {
|
630
802
|
var cache;
|
631
803
|
if (options == null) {
|
@@ -713,9 +885,38 @@
|
|
713
885
|
this._fail = false;
|
714
886
|
this._status = null;
|
715
887
|
this._error_message = null;
|
716
|
-
return this.camera.
|
888
|
+
return this.camera._engine_upload(this, cache.api_url, csrf_token, cache.timeout);
|
717
889
|
};
|
718
890
|
|
891
|
+
Snapshot.prototype._get_stats = function(data, callback) {
|
892
|
+
var gray, gray_values, i, index, mean, n, sum, sum_of_square_distances, _i, _j, _len;
|
893
|
+
if (!this._stats) {
|
894
|
+
n = data.width * data.height;
|
895
|
+
sum = 0.0;
|
896
|
+
gray_values = new Array(n);
|
897
|
+
for (i = _i = 0; _i < n; i = _i += 1) {
|
898
|
+
index = i * 4;
|
899
|
+
gray = 0.2126 * data.data[index + 0] + 0.7152 * data.data[index + 1] + 0.0722 * data.data[index + 2];
|
900
|
+
gray = Math.round(gray);
|
901
|
+
sum += gray;
|
902
|
+
gray_values[i] = gray;
|
903
|
+
}
|
904
|
+
mean = Math.round(sum / n);
|
905
|
+
sum_of_square_distances = 0;
|
906
|
+
for (_j = 0, _len = gray_values.length; _j < _len; _j++) {
|
907
|
+
gray = gray_values[_j];
|
908
|
+
sum_of_square_distances += Math.pow(gray - mean, 2);
|
909
|
+
}
|
910
|
+
this._stats = {
|
911
|
+
mean: mean,
|
912
|
+
std: Math.round(Math.sqrt(sum_of_square_distances / n))
|
913
|
+
};
|
914
|
+
}
|
915
|
+
return callback.call(this, this._stats);
|
916
|
+
};
|
917
|
+
|
918
|
+
Snapshot.prototype._stats = null;
|
919
|
+
|
719
920
|
Snapshot.prototype._upload_done = function() {
|
720
921
|
var cache, delay, retry_decision, that;
|
721
922
|
this.camera._debug("Upload completed with status " + this._status);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! JpegCamera 1.
|
1
|
+
/*! JpegCamera 1.1.1 | 2013-08-05
|
2
2
|
(c) 2013 Adam Wrobel
|
3
3
|
http://amw.github.io/jpeg_camera */
|
4
|
-
!function(){var a,b,c,d,e,f,g,h={}.hasOwnProperty,i=function(a,b){function c(){this.constructor=a}for(var d in b)h.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};a=function(){function a(a,b){if(this.container="string"==typeof a?document.querySelector(a):a,!this.container||!this.container.offsetWidth)throw"JpegCamera: invalid container";this.container.innerHTML="",this.options=this._extend({},this.constructor.DefaultOptions,b),this._engine_init()}return a.DefaultOptions={shutter_url:"/jpeg_camera/shutter.mp3",swf_url:"/jpeg_camera/jpeg_camera.swf",on_debug:function(a){return console&&console.log?console.log("JpegCamera: "+a):void 0},quality:.9,shutter:!0,mirror:!1,timeout:0,retry_success:!1},a.prototype.ready=function(a){return this.options.on_ready=a,this.options.on_ready&&this._is_ready&&this.options.on_ready.call(this),this},a.prototype._is_ready=!1,a.prototype.error=function(a){return this.options.on_error=a,this.options.on_error&&this._error_occured&&this.options.on_error.call(this,this._error_occured),this},a.prototype._error_occured=!1,a.prototype.capture=function(a){var b,c;return null==a&&(a={}),b=new d(this,a),this._snapshots[b.id]=b,c=b._options(),c.shutter&&this._engine_play_shutter_sound(),this._engine_capture(b,c.mirror,c.quality),b},a.prototype._snapshots={},a.prototype.show_stream=function(){return this._engine_show_stream(),this._displayed_snapshot=null,this},a.prototype.discard_all=function(){var a,b,c;this._displayed_snapshot&&this.show_stream(),c=this._snapshots;for(a in c)b=c[a],this._engine_discard(b),b._discarded=!0;return this._snapshots={},this},a.prototype._extend=function(a){var b,c,d,e,f,g;for(d=Array.prototype.slice.call(arguments,1),f=0,g=d.length;g>f;f++)if(c=d[f])for(b in c)e=c[b],a[b]=e;return a},a.prototype._debug=function(a){return this.options.on_debug?this.options.on_debug.call(this,a):void 0},a.prototype._view_width=function(){return parseInt(this.container.offsetWidth,10)},a.prototype._view_height=function(){return parseInt(this.container.offsetHeight,10)},a.prototype._display=function(a){return this._engine_display(a),this._displayed_snapshot=a},a.prototype._displayed_snapshot=null,a.prototype._upload=function(a,b,c,d){return this._engine_upload(a,b,c,d)},a.prototype._discard=function(a){return this._displayed_snapshot===a&&this.show_stream(),this._engine_discard(a),a._discarded=!0,delete this._snapshots[a.id]},a.prototype._prepared=function(){return this._is_ready=!0,this.options.on_ready?this.options.on_ready.call(this):void 0},a.prototype._got_error=function(a){return this._debug("Error - "+a),this._error_occured=a,this.options.on_error?this.options.on_error.call(this,this._error_occured):void 0},a}(),navigator.getUserMedia||(navigator.getUserMedia=navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia),navigator.getUserMedia&&(c=function(a){function b(){return f=b.__super__.constructor.apply(this,arguments)}return i(b,a),b.prototype._engine_init=function(){var a,b,c,d;return this._debug("Using HTML5 engine"),this.internal_container=document.createElement("div"),this.internal_container.style.width="100%",this.internal_container.style.height="100%",this.internal_container.style.position="relative",this.container.appendChild(this.internal_container),d=Math.floor(.2*this._view_height()),b=Math.floor(.2*this._view_width()),this.message=document.createElement("div"),this.message["class"]="message",this.message.style.width="100%",this.message.style.height="100%",this._add_prefixed_style(this.message,"boxSizing","border-box"),this.message.style.overflow="hidden",this.message.style.textAlign="center",this.message.style.paddingTop=""+d+"px",this.message.style.paddingBottom=""+d+"px",this.message.style.paddingLeft=""+b+"px",this.message.style.paddingRight=""+b+"px",this.message.style.position="absolute",this.message.style.zIndex=3,this.message.innerHTML="Please allow camera access when prompted by the browser.",this.internal_container.appendChild(this.message),this.video_container=document.createElement("div"),this.video_container.style.width=""+this._view_width()+"px",this.video_container.style.height=""+this._view_height()+"px",this.video_container.style.overflow="hidden",this.video_container.style.position="absolute",this.video_container.style.zIndex=1,this.internal_container.appendChild(this.video_container),this.video=document.createElement("video"),this.video.autoplay=!0,this._add_prefixed_style(this.video,"transform","scalex(-1.0)"),window.AudioContext||(window.AudioContext=window.webkitAudioContext),window.AudioContext&&this._load_shutter_sound(),a={video:{optional:[{minWidth:1280},{minWidth:640},{minWidth:480},{minWidth:360}]}},c=this,navigator.getUserMedia(a,function(a){return c._remove_message(),c.video.src=window.URL?URL.createObjectURL(a):a,c._wait_for_video_ready()},function(a){var b,d,e;b=a.code;for(d in a)if(e=a[d],"code"!==d)return c._got_error(d),void 0;return c._got_error("UNKNOWN ERROR")})},b.prototype._engine_play_shutter_sound=function(){var a;if(this.shutter_buffer)return a=this.audio_context.createBufferSource(),a.buffer=this.shutter_buffer,a.connect(this.audio_context.destination),a.start(0)},b.prototype._engine_capture=function(a,b,c){var d,e,f;return f=this._get_capture_crop(),d=document.createElement("canvas"),d.width=f.width,d.height=f.height,e=d.getContext("2d"),e.drawImage(this.video,f.x_offset,f.y_offset,f.width,f.height,0,0,f.width,f.height),a._canvas=d,a._mirror=b,a._quality=c},b.prototype._engine_display=function(a){return this.displayed_canvas&&this.internal_container.removeChild(this.displayed_canvas),this.displayed_canvas=a._canvas,this.displayed_canvas.style.width=""+this._view_width()+"px",this.displayed_canvas.style.height=""+this._view_height()+"px",this.displayed_canvas.style.top=0,this.displayed_canvas.style.left=0,this.displayed_canvas.style.position="absolute",this.displayed_canvas.style.zIndex=2,this._add_prefixed_style(this.displayed_canvas,"transform","scalex(-1.0)"),this.internal_container.appendChild(this.displayed_canvas)},b.prototype._engine_discard=function(a){return a._xhr&&a._xhr.abort(),delete a._xhr,delete a._canvas,delete a._jpeg_blob},b.prototype._engine_show_stream=function(){return this.displayed_canvas&&(this.internal_container.removeChild(this.displayed_canvas),this.displayed_canvas=null),this.video_container.style.display="block"},b.prototype._engine_upload=function(a,b,c,d){var e,f,g,h,i;return h=this,a._jpeg_blob?(this._debug("Uploading the file"),g=function(b){return delete a._xhr,a._status=b.target.status,a._response=b.target.responseText,a._status>=200&&a._status<300?a._upload_done():(a._error_message=b.target.statusText||"Unknown error",a._upload_fail())},i=new XMLHttpRequest,i.open("POST",b),i.timeout=d,c&&i.setRequestHeader("X-CSRF-Token",c),i.onload=g,i.onerror=g,i.onabort=g,i.send(a._jpeg_blob),a._xhr=i):(this._debug("Generating JPEG file"),a._mirror?(e=document.createElement("canvas"),e.width=a._canvas.width,e.height=a._canvas.height,f=e.getContext("2d"),f.setTransform(1,0,0,1,0,0),f.translate(e.width,0),f.scale(-1,1),f.drawImage(a._canvas,0,0)):e=a._canvas,e.toBlob(function(e){return a._jpeg_blob=e,h._engine_upload(a,b,c,d)},"image/jpeg",this.quality))},b.prototype._remove_message=function(){return this.message.style.display="none"},b.prototype._load_shutter_sound=function(){var a,b;if(!this.audio_context)return this.audio_context=new AudioContext,a=new XMLHttpRequest,a.open("GET",this.options.shutter_url,!0),a.responseType="arraybuffer",b=this,a.onload=function(){return b.audio_context.decodeAudioData(a.response,function(a){return b.shutter_buffer=a})},a.send()},b.prototype._wait_for_video_ready=function(){var a,b,c,d;return d=parseInt(this.video.videoWidth),c=parseInt(this.video.videoHeight),d>0&&c>0?(this.video_container.appendChild(this.video),this.video_width=d,this.video_height=c,this._debug("Camera resolution "+this.video_width+"x"+this.video_height+"px"),a=this._get_video_crop(),this.video.style.position="relative",this.video.style.width=""+a.width+"px",this.video.style.height=""+a.height+"px",this.video.style.left=""+a.x_offset+"px",this.video.style.top=""+a.y_offset+"px",this._prepared()):this._status_checks_count>100?this._got_error("Camera failed to initialize in 10 seconds"):(this._status_checks_count++,b=this,setTimeout(function(){return b._wait_for_video_ready()},100))},b.prototype._status_checks_count=0,b.prototype._add_prefixed_style=function(a,b,c){var d;return d=b.charAt(0).toUpperCase()+b.slice(1),a.style[b]=c,a.style["Webkit"+d]=c,a.style["Moz"+d]=c,a.style["ms"+d]=c,a.style["O"+d]=c},b.prototype._get_video_crop=function(){var a,b,c,d,e,f,g;return g=this._view_width(),e=this._view_height(),c=this.video_width/this.video_height,f=g/e,c>=f?(this._debug("Filling height"),d=e/this.video_height,b=Math.round(this.video_width*d),{width:b,height:e,x_offset:-Math.floor((b-g)/2),y_offset:0}):(this._debug("Filling width"),d=g/this.video_width,a=Math.round(this.video_height*d),{width:g,height:a,x_offset:0,y_offset:-Math.floor((a-e)/2)})},b.prototype._get_capture_crop=function(){var a,b,c,d,e,f;return f=this._view_width(),d=this._view_height(),c=this.video_width/this.video_height,e=f/d,c>=e?(b=Math.round(this.video_height*e),{width:b,height:this.video_height,x_offset:Math.floor((this.video_width-b)/2),y_offset:0}):(a=Math.round(this.video_width/e),{width:this.video_width,height:a,x_offset:0,y_offset:Math.floor((this.video_height-a)/2)})},b}(a),window.JpegCamera=c),e="9",!window.JpegCamera&&window.swfobject&&swfobject.hasFlashPlayerVersion(e)&&(b=function(a){function b(){return g=b.__super__.constructor.apply(this,arguments)}return i(b,a),b._send_message=function(a,b){var c,d;return(d=this._instances[parseInt(a)])?(c=Array.prototype.slice.call(arguments,2),this.prototype[b].apply(d,c)):void 0},b._instances={},b._next_id=1,b.prototype._engine_init=function(){var a,b,c,d,e,f,g,h;return this._debug("Using Flash engine"),this._id=this.constructor._next_id++,this.constructor._instances[this._id]=this,h=this._view_width(),e=this._view_height(),215>h||138>e?(this._got_error("camera is too small to display privacy dialog"),void 0):(c="flash_object_"+this._id,f={loop:"false",allowScriptAccess:"always",allowFullScreen:"false",quality:"best",wmode:"opaque",menu:"false"},a={id:c,align:"middle"},d={id:this._id,width:h,height:e,shutter_url:this.options.shutter_url},g=this,b=function(a){return a.success?(g._debug("Flash loaded"),g._flash=document.getElementById(c)):g._got_error("Flash loading failed.")},this.internal_container=document.createElement("div"),this.internal_container.id="jpeg_camera_flash_"+this._id,this.internal_container.style.width="100%",this.internal_container.style.height="100%",this.container.appendChild(this.internal_container),swfobject.embedSWF(this.options.swf_url,this.internal_container.id,h,e,"9",null,d,f,a,b))},b.prototype._engine_play_shutter_sound=function(){return this._flash._play_shutter()},b.prototype._engine_capture=function(a,b,c){return this._flash._capture(a.id,b,c)},b.prototype._engine_display=function(a){return this._flash._display(a.id)},b.prototype._engine_discard=function(a){return this._flash._discard(a.id)},b.prototype._engine_show_stream=function(){return this._flash._show_stream()},b.prototype._engine_upload=function(a,b,c,d){return this._flash._upload(a.id,b,c,d)},b.prototype._flash_prepared=function(){return this._prepared()},b.prototype._flash_upload_complete=function(a,b,c,d){var e;return a=parseInt(a),e=this._snapshots[a],e._status=parseInt(b),e._response=d,e._status>=200&&e._status<300?e._upload_done():(e._error_message=c,e._upload_fail())},b}(a),window.JpegCamera=b),d=function(){function a(a,b){this.camera=a,this.options=b,this.id=this.constructor._next_snapshot_id++}return a._next_snapshot_id=1,a.prototype._discarded=!1,a.prototype.show=function(){return this._discarded&&raise("discarded snapshot cannot be used"),this.camera._display(this),this},a.prototype.hide=function(){return this.camera.displayed_snapshot()===this&&this.camera.show_stream(),this},a.prototype.upload=function(a){var b;if(null==a&&(a={}),this._discarded&&raise("discarded snapshot cannot be used"),this._uploading)return this.camera._debug("Upload already in progress"),void 0;if(this._uploading=!0,this._retry=1,this._upload_options=a,b=this._options(),!b.api_url)throw this.camera._debug("Snapshot#upload called without valid api_url"),"Snapshot#upload called without valid api_url";return this._start_upload(b),this},a.prototype._upload_options={},a.prototype._uploading=!1,a.prototype._retry=1,a.prototype.done=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_done=a,b=this._options(),b.on_upload_done&&this._done&&b.on_upload_done.call(this,this._response),this},a.prototype._done=!1,a.prototype._response=null,a.prototype.fail=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_fail=a,b=this._options(),b.on_upload_fail&&this._fail&&b.on_upload_fail.call(this,this._status,this._error_message,this._response),this},a.prototype._fail=!1,a.prototype._status=null,a.prototype._error_message=null,a.prototype.discard=function(){return this.camera._discard(this),void 0},a.prototype._options=function(){return this.camera._extend({},this.camera.options,this.options,this._upload_options)},a.prototype._start_upload=function(a){var b;return b="string"==typeof a.csrf_token&&a.csrf_token.length>0?a.csrf_token:null,this._done=!1,this._response=null,this._fail=!1,this._status=null,this._error_message=null,this.camera._upload(this,a.api_url,b,a.timeout)},a.prototype._upload_done=function(){var a,b,c,d;return this.camera._debug("Upload completed with status "+this._status),this._done=!0,a=this._options(),c=a.retry_success&&a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_done?a.on_upload_done.call(this,this._response):void 0)},a.prototype._upload_fail=function(){var a,b,c,d;return this.camera._debug("Upload failed with status "+this._status),this._fail=!0,a=this._options(),c=a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_fail?a.on_upload_fail.call(this,this._status,this._error_message,this._response):void 0)},a}()}.call(this);
|
4
|
+
!function(){var a,b,c,d,e,f,g,h,i={}.hasOwnProperty,j=function(a,b){function c(){this.constructor=a}for(var d in b)i.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};if(a=function(){function a(a,b){if("string"==typeof a&&(a=document.getElementById(a.replace("#",""))),!a||!a.offsetWidth)throw"JpegCamera: invalid container";a.innerHTML="",this.container=document.createElement("div"),this.container.style.width="100%",this.container.style.height="100%",this.container.style.position="relative",a.appendChild(this.container),this.options=this._extend({},this.constructor.DefaultOptions,b),this._engine_init()}return a.DefaultOptions={shutter_url:"/jpeg_camera/shutter.mp3",swf_url:"/jpeg_camera/jpeg_camera.swf",on_debug:function(a){return console&&console.log?console.log("JpegCamera: "+a):void 0},quality:.9,shutter:!0,mirror:!1,timeout:0,retry_success:!1},a._canvas_supported=!!document.createElement("canvas").getContext,a.canvas_supported=function(){return this._canvas_supported},a.prototype.ready=function(a){return this.options.on_ready=a,this.options.on_ready&&this._is_ready&&this.options.on_ready.call(this),this},a.prototype._is_ready=!1,a.prototype.error=function(a){return this.options.on_error=a,this.options.on_error&&this._error_occured&&this.options.on_error.call(this,this._error_occured),this},a.prototype._error_occured=!1,a.StatsCaptureScale=.2,a.prototype.get_stats=function(b){var c,e;return c=new d(this,{}),this._engine_capture(c,!1,.1,a.StatsCaptureScale),e=this,c.get_stats(function(a){return b.call(e,a)})},a.prototype.capture=function(a){var b,c;return null==a&&(a={}),b=new d(this,a),this._snapshots[b.id]=b,c=b._options(),c.shutter&&this._engine_play_shutter_sound(),this._engine_capture(b,c.mirror,c.quality,1),b},a.prototype._snapshots={},a.prototype.show_stream=function(){return this._engine_show_stream(),this._displayed_snapshot=null,this},a.prototype.discard_all=function(){var a,b,c;this._displayed_snapshot&&this.show_stream(),c=this._snapshots;for(a in c)b=c[a],this._engine_discard(b),b._discarded=!0;return this._snapshots={},this},a.prototype._extend=function(a){var b,c,d,e,f,g;for(d=Array.prototype.slice.call(arguments,1),f=0,g=d.length;g>f;f++)if(c=d[f])for(b in c)e=c[b],a[b]=e;return a},a.prototype._debug=function(a){return this.options.on_debug?this.options.on_debug.call(this,a):void 0},a.prototype._view_width=function(){return parseInt(this.container.offsetWidth,10)},a.prototype._view_height=function(){return parseInt(this.container.offsetHeight,10)},a.prototype._display=function(a){return this._engine_display(a),this._displayed_snapshot=a},a.prototype._displayed_snapshot=null,a.prototype._discard=function(a){return this._displayed_snapshot===a&&this.show_stream(),this._engine_discard(a),a._discarded=!0,delete this._snapshots[a.id]},a.prototype._prepared=function(){var a;return a=this,setTimeout(function(){return a._wait_until_stream_looks_ok(!0)},1)},a.prototype._wait_until_stream_looks_ok=function(a){return this.get_stats(function(b){var c;return b.std>2?(this._debug("Stream mean gray value = "+b.mean+" standard deviation = "+b.std),this._debug("Camera is ready"),this._is_ready=!0,this.options.on_ready?this.options.on_ready.call(this):void 0):(a&&this._debug("Stream mean gray value = "+b.mean+" standard deviation = "+b.std),c=this,setTimeout(function(){return c._wait_until_stream_looks_ok(!1)},100))})},a.prototype._got_error=function(a){return this._debug("Error - "+a),this._error_occured=a,this.options.on_error?this.options.on_error.call(this,this._error_occured):void 0},a.prototype._block_element_access=function(){return this._overlay=document.createElement("div"),this._overlay.style.width="100%",this._overlay.style.height="100%",this._overlay.style.position="absolute",this._overlay.style.top=0,this._overlay.style.left=0,this._overlay.style.zIndex=2,this.container.appendChild(this._overlay)},a.prototype._overlay=null,a._add_prefixed_style=function(a,b,c){var d;return d=b.charAt(0).toUpperCase()+b.slice(1),a.style[b]=c,a.style["Webkit"+d]=c,a.style["Moz"+d]=c,a.style["ms"+d]=c,a.style["O"+d]=c},a}(),navigator.getUserMedia||(navigator.getUserMedia=navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia),e=function(){var a;if(a=document.createElement("canvas"),a.getContext&&!a.toBlob)throw"JpegCamera: Canvas-to-Blob is not loaded"},navigator.getUserMedia&&(e(),c=function(b){function c(){return g=c.__super__.constructor.apply(this,arguments)}return j(c,b),c.prototype._engine_init=function(){var b,c,d,e,f,g,h;this._debug("Using HTML5 engine"),h=Math.floor(.2*this._view_height()),e=Math.floor(.2*this._view_width()),this.message=document.createElement("div"),this.message["class"]="message",this.message.style.width="100%",this.message.style.height="100%",a._add_prefixed_style(this.message,"boxSizing","border-box"),this.message.style.overflow="hidden",this.message.style.textAlign="center",this.message.style.paddingTop=""+h+"px",this.message.style.paddingBottom=""+h+"px",this.message.style.paddingLeft=""+e+"px",this.message.style.paddingRight=""+e+"px",this.message.style.position="absolute",this.message.style.zIndex=3,this.message.innerHTML="Please allow camera access when prompted by the browser.<br><br>Look for camera icon around your address bar.",this.container.appendChild(this.message),this.video_container=document.createElement("div"),this.video_container.style.width=""+this._view_width()+"px",this.video_container.style.height=""+this._view_height()+"px",this.video_container.style.overflow="hidden",this.video_container.style.position="absolute",this.video_container.style.zIndex=1,this.container.appendChild(this.video_container),this.video=document.createElement("video"),this.video.autoplay=!0,a._add_prefixed_style(this.video,"transform","scalex(-1.0)"),window.AudioContext||(window.AudioContext=window.webkitAudioContext),window.AudioContext&&this._load_shutter_sound(),d={video:{optional:[{minWidth:1280},{minWidth:640},{minWidth:480},{minWidth:360}]}},g=this,f=function(a){return g._remove_message(),g.video.src=window.URL?URL.createObjectURL(a):a,g._block_element_access(),g._wait_for_video_ready()},c=function(a){var b,c,d;g.message.innerHTML='<span style="color: red;">You have denied camera access.</span><br><br>Look for camera icon around your address bar to change your decision.',b=a.code;for(c in a)if(d=a[c],"code"!==c)return g._got_error(c),void 0;return g._got_error("UNKNOWN ERROR")};try{return navigator.getUserMedia(d,f,c)}catch(i){return b=i,navigator.getUserMedia("video",f,c)}},c.prototype._engine_play_shutter_sound=function(){var a;if(this.shutter_buffer)return a=this.audio_context.createBufferSource(),a.buffer=this.shutter_buffer,a.connect(this.audio_context.destination),a.start(0)},c.prototype._engine_capture=function(a,b,c,d){var e,f,g;return g=this._get_capture_crop(),e=document.createElement("canvas"),e.width=Math.round(g.width*d),e.height=Math.round(g.height*d),f=e.getContext("2d"),f.drawImage(this.video,g.x_offset,g.y_offset,g.width,g.height,0,0,Math.round(g.width*d),Math.round(g.height*d)),a._canvas=e,a._mirror=b,a._quality=c},c.prototype._engine_display=function(b){return this.displayed_canvas&&this.container.removeChild(this.displayed_canvas),this.displayed_canvas=b._canvas,this.displayed_canvas.style.width=""+this._view_width()+"px",this.displayed_canvas.style.height=""+this._view_height()+"px",this.displayed_canvas.style.top=0,this.displayed_canvas.style.left=0,this.displayed_canvas.style.position="absolute",this.displayed_canvas.style.zIndex=2,a._add_prefixed_style(this.displayed_canvas,"transform","scalex(-1.0)"),this.container.appendChild(this.displayed_canvas)},c.prototype._engine_get_canvas=function(a){var b,c;return b=document.createElement("canvas"),b.width=a._canvas.width,b.height=a._canvas.height,c=b.getContext("2d"),c.drawImage(a._canvas,0,0),b},c.prototype._engine_get_image_data=function(a){var b,c;return b=a._canvas,c=b.getContext("2d"),c.getImageData(0,0,b.width,b.height)},c.prototype._engine_discard=function(a){return a._xhr&&a._xhr.abort(),delete a._xhr,delete a._canvas,delete a._jpeg_blob},c.prototype._engine_show_stream=function(){return this.displayed_canvas&&(this.container.removeChild(this.displayed_canvas),this.displayed_canvas=null),this.video_container.style.display="block"},c.prototype._engine_upload=function(a,b,c,d){var e,f,g,h,i;return h=this,a._jpeg_blob?(this._debug("Uploading the file"),g=function(b){return delete a._xhr,a._status=b.target.status,a._response=b.target.responseText,a._status>=200&&a._status<300?a._upload_done():(a._error_message=b.target.statusText||"Unknown error",a._upload_fail())},i=new XMLHttpRequest,i.open("POST",b),i.timeout=d,c&&i.setRequestHeader("X-CSRF-Token",c),i.onload=g,i.onerror=g,i.onabort=g,i.send(a._jpeg_blob),a._xhr=i):(this._debug("Generating JPEG file"),a._mirror?(e=document.createElement("canvas"),e.width=a._canvas.width,e.height=a._canvas.height,f=e.getContext("2d"),f.setTransform(1,0,0,1,0,0),f.translate(e.width,0),f.scale(-1,1),f.drawImage(a._canvas,0,0)):e=a._canvas,e.toBlob(function(e){return a._jpeg_blob=e,h._engine_upload(a,b,c,d)},"image/jpeg",this.quality))},c.prototype._remove_message=function(){return this.message.style.display="none"},c.prototype._load_shutter_sound=function(){var a,b;if(!this.audio_context)return this.audio_context=new AudioContext,a=new XMLHttpRequest,a.open("GET",this.options.shutter_url,!0),a.responseType="arraybuffer",b=this,a.onload=function(){return b.audio_context.decodeAudioData(a.response,function(a){return b.shutter_buffer=a})},a.send()},c.prototype._wait_for_video_ready=function(){var a,b,c,d;return d=parseInt(this.video.videoWidth),c=parseInt(this.video.videoHeight),d>0&&c>0?(this.video_container.appendChild(this.video),this.video_width=d,this.video_height=c,this._debug("Camera resolution "+this.video_width+"x"+this.video_height+"px"),a=this._get_video_crop(),this.video.style.position="relative",this.video.style.width=""+a.width+"px",this.video.style.height=""+a.height+"px",this.video.style.left=""+a.x_offset+"px",this.video.style.top=""+a.y_offset+"px",this._prepared()):this._status_checks_count>100?this._got_error("Camera failed to initialize in 10 seconds"):(this._status_checks_count++,b=this,setTimeout(function(){return b._wait_for_video_ready()},100))},c.prototype._status_checks_count=0,c.prototype._get_video_crop=function(){var a,b,c,d,e,f,g;return g=this._view_width(),e=this._view_height(),c=this.video_width/this.video_height,f=g/e,c>=f?(this._debug("Filling height"),d=e/this.video_height,b=Math.round(this.video_width*d),{width:b,height:e,x_offset:-Math.floor((b-g)/2),y_offset:0}):(this._debug("Filling width"),d=g/this.video_width,a=Math.round(this.video_height*d),{width:g,height:a,x_offset:0,y_offset:-Math.floor((a-e)/2)})},c.prototype._get_capture_crop=function(){var a,b,c,d,e,f;return f=this._view_width(),d=this._view_height(),c=this.video_width/this.video_height,e=f/d,c>=e?(b=Math.round(this.video_height*e),{width:b,height:this.video_height,x_offset:Math.floor((this.video_width-b)/2),y_offset:0}):(a=Math.round(this.video_width/e),{width:this.video_width,height:a,x_offset:0,y_offset:Math.floor((this.video_height-a)/2)})},c}(a),window.JpegCamera=c),f="9",!window.swfobject)throw"JpegCamera: SWFObject is not loaded";!window.JpegCamera&&window.swfobject&&swfobject.hasFlashPlayerVersion(f)&&(b=function(b){function c(){return h=c.__super__.constructor.apply(this,arguments)}return j(c,b),c._send_message=function(a,b){var c,d;return(d=this._instances[parseInt(a)])?(c=Array.prototype.slice.call(arguments,2),this.prototype[b].apply(d,c)):void 0},c._instances={},c._next_id=1,c.prototype._engine_init=function(){var a,b,c,d,e,f,g,h,i;return this._debug("Using Flash engine"),this._id=this.constructor._next_id++,this.constructor._instances[this._id]=this,i=this._view_width(),f=this._view_height(),215>i||138>f?(this._got_error("camera is too small to display privacy dialog"),void 0):(d="flash_object_"+this._id,g={loop:"false",allowScriptAccess:"always",allowFullScreen:"false",quality:"best",wmode:"opaque",menu:"false"},a={id:d,align:"middle"},e={id:this._id,width:i,height:f,shutter_url:this.options.shutter_url},h=this,b=function(a){return a.success?(h._debug("Flash loaded"),h._flash=document.getElementById(d)):h._got_error("Flash loading failed.")},c=document.createElement("div"),c.id="jpeg_camera_flash_"+this._id,c.style.width="100%",c.style.height="100%",this.container.appendChild(c),swfobject.embedSWF(this.options.swf_url,c.id,i,f,"9",null,e,g,a,b))},c.prototype._engine_play_shutter_sound=function(){return this._flash._play_shutter()},c.prototype._engine_capture=function(a,b,c,d){return this._flash._capture(a.id,b,c,d)},c.prototype._engine_display=function(a){return this._flash._display(a.id)},c.prototype._engine_get_canvas=function(a){var b,c;return a._image_data||(a._image_data=this._engine_get_image_data(a)),b=document.createElement("canvas"),b.width=a._image_data.width,b.height=a._image_data.height,c=b.getContext("2d"),c.putImageData(a._image_data,0,0),b},c.prototype._engine_get_image_data=function(b){var c,d,e,f,g,h,i,j,k,l,m,n,o;for(f=this._flash._get_image_data(b.id),a.canvas_supported()?(d=document.createElement("canvas"),d.width=f.width,d.height=f.height,e=d.getContext("2d"),l=e.createImageData(f.width,f.height)):l={data:[],width:f.width,height:f.height},o=f.data,h=m=0,n=o.length;n>m;h=++m)j=o[h],i=4*h,k=255&j>>16,g=255&j>>8,c=255&j,l.data[i+0]=k,l.data[i+1]=g,l.data[i+2]=c,l.data[i+3]=255;return l},c.prototype._engine_discard=function(a){return this._flash._discard(a.id)},c.prototype._engine_show_stream=function(){return this._flash._show_stream()},c.prototype._engine_upload=function(a,b,c,d){return this._flash._upload(a.id,b,c,d)},c.prototype._flash_prepared=function(){return this._block_element_access(),this._prepared()},c.prototype._flash_upload_complete=function(a,b,c,d){var e;return a=parseInt(a),e=this._snapshots[a],e._status=parseInt(b),e._response=d,e._status>=200&&e._status<300?e._upload_done():(e._error_message=c,e._upload_fail())},c}(a),window.JpegCamera=b),d=function(){function b(a,b){this.camera=a,this.options=b,this.id=this.constructor._next_snapshot_id++}return b._next_snapshot_id=1,b.prototype._discarded=!1,b.prototype.show=function(){return this._discarded&&raise("discarded snapshot cannot be used"),this.camera._display(this),this},b.prototype.hide=function(){return this.camera.displayed_snapshot()===this&&this.camera.show_stream(),this},b.prototype.get_stats=function(a){return this._discarded&&raise("discarded snapshot cannot be used"),this.get_image_data(function(b){return this._get_stats(b,a)})},b.prototype.get_canvas=function(b){var c;return this._discarded&&raise("discarded snapshot cannot be used"),!a._canvas_supported,c=this,setTimeout(function(){return c._extra_canvas||(c._extra_canvas=c.camera._engine_get_canvas(c)),a._add_prefixed_style(c._extra_canvas,"transform","scalex(-1.0)"),b.call(c,c._extra_canvas)},10),!0},b.prototype._extra_canvas=null,b.prototype.get_image_data=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),b=this,setTimeout(function(){return b._image_data||(b._image_data=b.camera._engine_get_image_data(b)),a.call(b,b._image_data)},5)},b.prototype._image_data=null,b.prototype.upload=function(a){var b;if(null==a&&(a={}),this._discarded&&raise("discarded snapshot cannot be used"),this._uploading)return this.camera._debug("Upload already in progress"),void 0;if(this._uploading=!0,this._retry=1,this._upload_options=a,b=this._options(),!b.api_url)throw this.camera._debug("Snapshot#upload called without valid api_url"),"Snapshot#upload called without valid api_url";return this._start_upload(b),this},b.prototype._upload_options={},b.prototype._uploading=!1,b.prototype._retry=1,b.prototype.done=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_done=a,b=this._options(),b.on_upload_done&&this._done&&b.on_upload_done.call(this,this._response),this},b.prototype._done=!1,b.prototype._response=null,b.prototype.fail=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_fail=a,b=this._options(),b.on_upload_fail&&this._fail&&b.on_upload_fail.call(this,this._status,this._error_message,this._response),this},b.prototype._fail=!1,b.prototype._status=null,b.prototype._error_message=null,b.prototype.discard=function(){return this.camera._discard(this),void 0},b.prototype._options=function(){return this.camera._extend({},this.camera.options,this.options,this._upload_options)},b.prototype._start_upload=function(a){var b;return b="string"==typeof a.csrf_token&&a.csrf_token.length>0?a.csrf_token:null,this._done=!1,this._response=null,this._fail=!1,this._status=null,this._error_message=null,this.camera._engine_upload(this,a.api_url,b,a.timeout)},b.prototype._get_stats=function(a,b){var c,d,e,f,g,h,i,j,k,l,m;if(!this._stats){for(h=a.width*a.height,i=0,d=new Array(h),e=k=0;h>k;e=k+=1)f=4*e,c=.2126*a.data[f+0]+.7152*a.data[f+1]+.0722*a.data[f+2],c=Math.round(c),i+=c,d[e]=c;for(g=Math.round(i/h),j=0,l=0,m=d.length;m>l;l++)c=d[l],j+=Math.pow(c-g,2);this._stats={mean:g,std:Math.round(Math.sqrt(j/h))}}return b.call(this,this._stats)},b.prototype._stats=null,b.prototype._upload_done=function(){var a,b,c,d;return this.camera._debug("Upload completed with status "+this._status),this._done=!0,a=this._options(),c=a.retry_success&&a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_done?a.on_upload_done.call(this,this._response):void 0)},b.prototype._upload_fail=function(){var a,b,c,d;return this.camera._debug("Upload failed with status "+this._status),this._fail=!0,a=this._options(),c=a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_fail?a.on_upload_fail.call(this,this._status,this._error_message,this._response):void 0)},b}()}.call(this);
|
@@ -1,8 +1,8 @@
|
|
1
|
-
/*! JpegCamera 1.
|
1
|
+
/*! JpegCamera 1.1.1 | 2013-08-05
|
2
2
|
(c) 2013 Adam Wrobel
|
3
3
|
http://amw.github.io/jpeg_camera */
|
4
4
|
(function() {
|
5
|
-
var JpegCamera, JpegCameraHtml5, Snapshot, _ref,
|
5
|
+
var JpegCamera, JpegCameraHtml5, Snapshot, check_canvas_to_blob, _ref,
|
6
6
|
__hasProp = {}.hasOwnProperty,
|
7
7
|
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
8
8
|
|
@@ -22,16 +22,25 @@
|
|
22
22
|
retry_success: false
|
23
23
|
};
|
24
24
|
|
25
|
+
JpegCamera._canvas_supported = !!document.createElement('canvas').getContext;
|
26
|
+
|
27
|
+
JpegCamera.canvas_supported = function() {
|
28
|
+
return this._canvas_supported;
|
29
|
+
};
|
30
|
+
|
25
31
|
function JpegCamera(container, options) {
|
26
32
|
if ("string" === typeof container) {
|
27
|
-
|
28
|
-
} else {
|
29
|
-
this.container = container;
|
33
|
+
container = document.getElementById(container.replace("#", ""));
|
30
34
|
}
|
31
|
-
if (!(
|
35
|
+
if (!(container && container.offsetWidth)) {
|
32
36
|
throw "JpegCamera: invalid container";
|
33
37
|
}
|
34
|
-
|
38
|
+
container.innerHTML = "";
|
39
|
+
this.container = document.createElement("div");
|
40
|
+
this.container.style.width = "100%";
|
41
|
+
this.container.style.height = "100%";
|
42
|
+
this.container.style.position = "relative";
|
43
|
+
container.appendChild(this.container);
|
35
44
|
this.options = this._extend({}, this.constructor.DefaultOptions, options);
|
36
45
|
this._engine_init();
|
37
46
|
}
|
@@ -56,6 +65,18 @@
|
|
56
65
|
|
57
66
|
JpegCamera.prototype._error_occured = false;
|
58
67
|
|
68
|
+
JpegCamera.StatsCaptureScale = 0.2;
|
69
|
+
|
70
|
+
JpegCamera.prototype.get_stats = function(callback) {
|
71
|
+
var snapshot, that;
|
72
|
+
snapshot = new Snapshot(this, {});
|
73
|
+
this._engine_capture(snapshot, false, 0.1, JpegCamera.StatsCaptureScale);
|
74
|
+
that = this;
|
75
|
+
return snapshot.get_stats(function(stats) {
|
76
|
+
return callback.call(that, stats);
|
77
|
+
});
|
78
|
+
};
|
79
|
+
|
59
80
|
JpegCamera.prototype.capture = function(options) {
|
60
81
|
var snapshot, _options;
|
61
82
|
if (options == null) {
|
@@ -67,7 +88,7 @@
|
|
67
88
|
if (_options.shutter) {
|
68
89
|
this._engine_play_shutter_sound();
|
69
90
|
}
|
70
|
-
this._engine_capture(snapshot, _options.mirror, _options.quality);
|
91
|
+
this._engine_capture(snapshot, _options.mirror, _options.quality, 1.0);
|
71
92
|
return snapshot;
|
72
93
|
};
|
73
94
|
|
@@ -130,10 +151,6 @@
|
|
130
151
|
|
131
152
|
JpegCamera.prototype._displayed_snapshot = null;
|
132
153
|
|
133
|
-
JpegCamera.prototype._upload = function(snapshot, api_url, csrf_token, timeout) {
|
134
|
-
return this._engine_upload(snapshot, api_url, csrf_token, timeout);
|
135
|
-
};
|
136
|
-
|
137
154
|
JpegCamera.prototype._discard = function(snapshot) {
|
138
155
|
if (this._displayed_snapshot === snapshot) {
|
139
156
|
this.show_stream();
|
@@ -144,10 +161,33 @@
|
|
144
161
|
};
|
145
162
|
|
146
163
|
JpegCamera.prototype._prepared = function() {
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
164
|
+
var that;
|
165
|
+
that = this;
|
166
|
+
return setTimeout((function() {
|
167
|
+
return that._wait_until_stream_looks_ok(true);
|
168
|
+
}), 1);
|
169
|
+
};
|
170
|
+
|
171
|
+
JpegCamera.prototype._wait_until_stream_looks_ok = function(show_debug) {
|
172
|
+
return this.get_stats(function(stats) {
|
173
|
+
var that;
|
174
|
+
if (stats.std > 2) {
|
175
|
+
this._debug("Stream mean gray value = " + stats.mean + " standard deviation = " + stats.std);
|
176
|
+
this._debug("Camera is ready");
|
177
|
+
this._is_ready = true;
|
178
|
+
if (this.options.on_ready) {
|
179
|
+
return this.options.on_ready.call(this);
|
180
|
+
}
|
181
|
+
} else {
|
182
|
+
if (show_debug) {
|
183
|
+
this._debug("Stream mean gray value = " + stats.mean + " standard deviation = " + stats.std);
|
184
|
+
}
|
185
|
+
that = this;
|
186
|
+
return setTimeout((function() {
|
187
|
+
return that._wait_until_stream_looks_ok(false);
|
188
|
+
}), 100);
|
189
|
+
}
|
190
|
+
});
|
151
191
|
};
|
152
192
|
|
153
193
|
JpegCamera.prototype._got_error = function(error) {
|
@@ -158,13 +198,45 @@
|
|
158
198
|
}
|
159
199
|
};
|
160
200
|
|
201
|
+
JpegCamera.prototype._block_element_access = function() {
|
202
|
+
this._overlay = document.createElement("div");
|
203
|
+
this._overlay.style.width = "100%";
|
204
|
+
this._overlay.style.height = "100%";
|
205
|
+
this._overlay.style.position = "absolute";
|
206
|
+
this._overlay.style.top = 0;
|
207
|
+
this._overlay.style.left = 0;
|
208
|
+
this._overlay.style.zIndex = 2;
|
209
|
+
return this.container.appendChild(this._overlay);
|
210
|
+
};
|
211
|
+
|
212
|
+
JpegCamera.prototype._overlay = null;
|
213
|
+
|
214
|
+
JpegCamera._add_prefixed_style = function(element, style, value) {
|
215
|
+
var uppercase_style;
|
216
|
+
uppercase_style = style.charAt(0).toUpperCase() + style.slice(1);
|
217
|
+
element.style[style] = value;
|
218
|
+
element.style["Webkit" + uppercase_style] = value;
|
219
|
+
element.style["Moz" + uppercase_style] = value;
|
220
|
+
element.style["ms" + uppercase_style] = value;
|
221
|
+
return element.style["O" + uppercase_style] = value;
|
222
|
+
};
|
223
|
+
|
161
224
|
return JpegCamera;
|
162
225
|
|
163
226
|
})();
|
164
227
|
|
165
228
|
navigator.getUserMedia || (navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
|
166
229
|
|
230
|
+
check_canvas_to_blob = function() {
|
231
|
+
var canvas;
|
232
|
+
canvas = document.createElement("canvas");
|
233
|
+
if (canvas.getContext && !canvas.toBlob) {
|
234
|
+
throw "JpegCamera: Canvas-to-Blob is not loaded";
|
235
|
+
}
|
236
|
+
};
|
237
|
+
|
167
238
|
if (navigator.getUserMedia) {
|
239
|
+
check_canvas_to_blob();
|
168
240
|
JpegCameraHtml5 = (function(_super) {
|
169
241
|
__extends(JpegCameraHtml5, _super);
|
170
242
|
|
@@ -174,20 +246,15 @@
|
|
174
246
|
}
|
175
247
|
|
176
248
|
JpegCameraHtml5.prototype._engine_init = function() {
|
177
|
-
var get_user_media_options, horizontal_padding, that, vertical_padding;
|
249
|
+
var error, failure, get_user_media_options, horizontal_padding, success, that, vertical_padding;
|
178
250
|
this._debug("Using HTML5 engine");
|
179
|
-
this.internal_container = document.createElement("div");
|
180
|
-
this.internal_container.style.width = "100%";
|
181
|
-
this.internal_container.style.height = "100%";
|
182
|
-
this.internal_container.style.position = "relative";
|
183
|
-
this.container.appendChild(this.internal_container);
|
184
251
|
vertical_padding = Math.floor(this._view_height() * 0.2);
|
185
252
|
horizontal_padding = Math.floor(this._view_width() * 0.2);
|
186
253
|
this.message = document.createElement("div");
|
187
254
|
this.message["class"] = "message";
|
188
255
|
this.message.style.width = "100%";
|
189
256
|
this.message.style.height = "100%";
|
190
|
-
|
257
|
+
JpegCamera._add_prefixed_style(this.message, "boxSizing", "border-box");
|
191
258
|
this.message.style.overflow = "hidden";
|
192
259
|
this.message.style.textAlign = "center";
|
193
260
|
this.message.style.paddingTop = "" + vertical_padding + "px";
|
@@ -196,18 +263,18 @@
|
|
196
263
|
this.message.style.paddingRight = "" + horizontal_padding + "px";
|
197
264
|
this.message.style.position = "absolute";
|
198
265
|
this.message.style.zIndex = 3;
|
199
|
-
this.message.innerHTML = "Please allow camera access when prompted by the browser.";
|
200
|
-
this.
|
266
|
+
this.message.innerHTML = "Please allow camera access when prompted by the browser.<br><br>" + "Look for camera icon around your address bar.";
|
267
|
+
this.container.appendChild(this.message);
|
201
268
|
this.video_container = document.createElement("div");
|
202
269
|
this.video_container.style.width = "" + (this._view_width()) + "px";
|
203
270
|
this.video_container.style.height = "" + (this._view_height()) + "px";
|
204
271
|
this.video_container.style.overflow = "hidden";
|
205
272
|
this.video_container.style.position = "absolute";
|
206
273
|
this.video_container.style.zIndex = 1;
|
207
|
-
this.
|
274
|
+
this.container.appendChild(this.video_container);
|
208
275
|
this.video = document.createElement('video');
|
209
276
|
this.video.autoplay = true;
|
210
|
-
|
277
|
+
JpegCamera._add_prefixed_style(this.video, "transform", "scalex(-1.0)");
|
211
278
|
window.AudioContext || (window.AudioContext = window.webkitAudioContext);
|
212
279
|
if (window.AudioContext) {
|
213
280
|
this._load_shutter_sound();
|
@@ -228,16 +295,19 @@
|
|
228
295
|
}
|
229
296
|
};
|
230
297
|
that = this;
|
231
|
-
|
298
|
+
success = function(stream) {
|
232
299
|
that._remove_message();
|
233
300
|
if (window.URL) {
|
234
301
|
that.video.src = URL.createObjectURL(stream);
|
235
302
|
} else {
|
236
303
|
that.video.src = stream;
|
237
304
|
}
|
305
|
+
that._block_element_access();
|
238
306
|
return that._wait_for_video_ready();
|
239
|
-
}
|
307
|
+
};
|
308
|
+
failure = function(error) {
|
240
309
|
var code, key, value;
|
310
|
+
that.message.innerHTML = "<span style=\"color: red;\">" + "You have denied camera access." + "</span><br><br>" + "Look for camera icon around your address bar to change your " + "decision.";
|
241
311
|
code = error.code;
|
242
312
|
for (key in error) {
|
243
313
|
value = error[key];
|
@@ -248,7 +318,13 @@
|
|
248
318
|
return;
|
249
319
|
}
|
250
320
|
return that._got_error("UNKNOWN ERROR");
|
251
|
-
}
|
321
|
+
};
|
322
|
+
try {
|
323
|
+
return navigator.getUserMedia(get_user_media_options, success, failure);
|
324
|
+
} catch (_error) {
|
325
|
+
error = _error;
|
326
|
+
return navigator.getUserMedia("video", success, failure);
|
327
|
+
}
|
252
328
|
};
|
253
329
|
|
254
330
|
JpegCameraHtml5.prototype._engine_play_shutter_sound = function() {
|
@@ -262,14 +338,14 @@
|
|
262
338
|
return source.start(0);
|
263
339
|
};
|
264
340
|
|
265
|
-
JpegCameraHtml5.prototype._engine_capture = function(snapshot, mirror, quality) {
|
341
|
+
JpegCameraHtml5.prototype._engine_capture = function(snapshot, mirror, quality, scale) {
|
266
342
|
var canvas, context, crop;
|
267
343
|
crop = this._get_capture_crop();
|
268
344
|
canvas = document.createElement("canvas");
|
269
|
-
canvas.width = crop.width;
|
270
|
-
canvas.height = crop.height;
|
345
|
+
canvas.width = Math.round(crop.width * scale);
|
346
|
+
canvas.height = Math.round(crop.height * scale);
|
271
347
|
context = canvas.getContext("2d");
|
272
|
-
context.drawImage(this.video, crop.x_offset, crop.y_offset, crop.width, crop.height, 0, 0, crop.width, crop.height);
|
348
|
+
context.drawImage(this.video, crop.x_offset, crop.y_offset, crop.width, crop.height, 0, 0, Math.round(crop.width * scale), Math.round(crop.height * scale));
|
273
349
|
snapshot._canvas = canvas;
|
274
350
|
snapshot._mirror = mirror;
|
275
351
|
return snapshot._quality = quality;
|
@@ -277,7 +353,7 @@
|
|
277
353
|
|
278
354
|
JpegCameraHtml5.prototype._engine_display = function(snapshot) {
|
279
355
|
if (this.displayed_canvas) {
|
280
|
-
this.
|
356
|
+
this.container.removeChild(this.displayed_canvas);
|
281
357
|
}
|
282
358
|
this.displayed_canvas = snapshot._canvas;
|
283
359
|
this.displayed_canvas.style.width = "" + (this._view_width()) + "px";
|
@@ -286,8 +362,25 @@
|
|
286
362
|
this.displayed_canvas.style.left = 0;
|
287
363
|
this.displayed_canvas.style.position = "absolute";
|
288
364
|
this.displayed_canvas.style.zIndex = 2;
|
289
|
-
|
290
|
-
return this.
|
365
|
+
JpegCamera._add_prefixed_style(this.displayed_canvas, "transform", "scalex(-1.0)");
|
366
|
+
return this.container.appendChild(this.displayed_canvas);
|
367
|
+
};
|
368
|
+
|
369
|
+
JpegCameraHtml5.prototype._engine_get_canvas = function(snapshot) {
|
370
|
+
var canvas, context;
|
371
|
+
canvas = document.createElement("canvas");
|
372
|
+
canvas.width = snapshot._canvas.width;
|
373
|
+
canvas.height = snapshot._canvas.height;
|
374
|
+
context = canvas.getContext("2d");
|
375
|
+
context.drawImage(snapshot._canvas, 0, 0);
|
376
|
+
return canvas;
|
377
|
+
};
|
378
|
+
|
379
|
+
JpegCameraHtml5.prototype._engine_get_image_data = function(snapshot) {
|
380
|
+
var canvas, context;
|
381
|
+
canvas = snapshot._canvas;
|
382
|
+
context = canvas.getContext("2d");
|
383
|
+
return context.getImageData(0, 0, canvas.width, canvas.height);
|
291
384
|
};
|
292
385
|
|
293
386
|
JpegCameraHtml5.prototype._engine_discard = function(snapshot) {
|
@@ -301,7 +394,7 @@
|
|
301
394
|
|
302
395
|
JpegCameraHtml5.prototype._engine_show_stream = function() {
|
303
396
|
if (this.displayed_canvas) {
|
304
|
-
this.
|
397
|
+
this.container.removeChild(this.displayed_canvas);
|
305
398
|
this.displayed_canvas = null;
|
306
399
|
}
|
307
400
|
return this.video_container.style.display = "block";
|
@@ -406,16 +499,6 @@
|
|
406
499
|
|
407
500
|
JpegCameraHtml5.prototype._status_checks_count = 0;
|
408
501
|
|
409
|
-
JpegCameraHtml5.prototype._add_prefixed_style = function(element, style, value) {
|
410
|
-
var uppercase_style;
|
411
|
-
uppercase_style = style.charAt(0).toUpperCase() + style.slice(1);
|
412
|
-
element.style[style] = value;
|
413
|
-
element.style["Webkit" + uppercase_style] = value;
|
414
|
-
element.style["Moz" + uppercase_style] = value;
|
415
|
-
element.style["ms" + uppercase_style] = value;
|
416
|
-
return element.style["O" + uppercase_style] = value;
|
417
|
-
};
|
418
|
-
|
419
502
|
JpegCameraHtml5.prototype._get_video_crop = function() {
|
420
503
|
var scaled_video_height, scaled_video_width, video_ratio, video_scale, view_height, view_ratio, view_width;
|
421
504
|
view_width = this._view_width();
|
@@ -506,6 +589,48 @@
|
|
506
589
|
return this;
|
507
590
|
};
|
508
591
|
|
592
|
+
Snapshot.prototype.get_stats = function(callback) {
|
593
|
+
if (this._discarded) {
|
594
|
+
raise("discarded snapshot cannot be used");
|
595
|
+
}
|
596
|
+
return this.get_image_data(function(data) {
|
597
|
+
return this._get_stats(data, callback);
|
598
|
+
});
|
599
|
+
};
|
600
|
+
|
601
|
+
Snapshot.prototype.get_canvas = function(callback) {
|
602
|
+
var that;
|
603
|
+
if (this._discarded) {
|
604
|
+
raise("discarded snapshot cannot be used");
|
605
|
+
}
|
606
|
+
if (!JpegCamera._canvas_supported) {
|
607
|
+
false;
|
608
|
+
}
|
609
|
+
that = this;
|
610
|
+
setTimeout(function() {
|
611
|
+
that._extra_canvas || (that._extra_canvas = that.camera._engine_get_canvas(that));
|
612
|
+
JpegCamera._add_prefixed_style(that._extra_canvas, "transform", "scalex(-1.0)");
|
613
|
+
return callback.call(that, that._extra_canvas);
|
614
|
+
}, 10);
|
615
|
+
return true;
|
616
|
+
};
|
617
|
+
|
618
|
+
Snapshot.prototype._extra_canvas = null;
|
619
|
+
|
620
|
+
Snapshot.prototype.get_image_data = function(callback) {
|
621
|
+
var that;
|
622
|
+
if (this._discarded) {
|
623
|
+
raise("discarded snapshot cannot be used");
|
624
|
+
}
|
625
|
+
that = this;
|
626
|
+
return setTimeout(function() {
|
627
|
+
that._image_data || (that._image_data = that.camera._engine_get_image_data(that));
|
628
|
+
return callback.call(that, that._image_data);
|
629
|
+
}, 5);
|
630
|
+
};
|
631
|
+
|
632
|
+
Snapshot.prototype._image_data = null;
|
633
|
+
|
509
634
|
Snapshot.prototype.upload = function(options) {
|
510
635
|
var cache;
|
511
636
|
if (options == null) {
|
@@ -593,9 +718,38 @@
|
|
593
718
|
this._fail = false;
|
594
719
|
this._status = null;
|
595
720
|
this._error_message = null;
|
596
|
-
return this.camera.
|
721
|
+
return this.camera._engine_upload(this, cache.api_url, csrf_token, cache.timeout);
|
597
722
|
};
|
598
723
|
|
724
|
+
Snapshot.prototype._get_stats = function(data, callback) {
|
725
|
+
var gray, gray_values, i, index, mean, n, sum, sum_of_square_distances, _i, _j, _len;
|
726
|
+
if (!this._stats) {
|
727
|
+
n = data.width * data.height;
|
728
|
+
sum = 0.0;
|
729
|
+
gray_values = new Array(n);
|
730
|
+
for (i = _i = 0; _i < n; i = _i += 1) {
|
731
|
+
index = i * 4;
|
732
|
+
gray = 0.2126 * data.data[index + 0] + 0.7152 * data.data[index + 1] + 0.0722 * data.data[index + 2];
|
733
|
+
gray = Math.round(gray);
|
734
|
+
sum += gray;
|
735
|
+
gray_values[i] = gray;
|
736
|
+
}
|
737
|
+
mean = Math.round(sum / n);
|
738
|
+
sum_of_square_distances = 0;
|
739
|
+
for (_j = 0, _len = gray_values.length; _j < _len; _j++) {
|
740
|
+
gray = gray_values[_j];
|
741
|
+
sum_of_square_distances += Math.pow(gray - mean, 2);
|
742
|
+
}
|
743
|
+
this._stats = {
|
744
|
+
mean: mean,
|
745
|
+
std: Math.round(Math.sqrt(sum_of_square_distances / n))
|
746
|
+
};
|
747
|
+
}
|
748
|
+
return callback.call(this, this._stats);
|
749
|
+
};
|
750
|
+
|
751
|
+
Snapshot.prototype._stats = null;
|
752
|
+
|
599
753
|
Snapshot.prototype._upload_done = function() {
|
600
754
|
var cache, delay, retry_decision, that;
|
601
755
|
this.camera._debug("Upload completed with status " + this._status);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! JpegCamera 1.
|
1
|
+
/*! JpegCamera 1.1.1 | 2013-08-05
|
2
2
|
(c) 2013 Adam Wrobel
|
3
3
|
http://amw.github.io/jpeg_camera */
|
4
|
-
!function(){var a,b,c,d,e={}.hasOwnProperty,f=function(a,b){function c(){this.constructor=a}for(var d in b)e.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};a=function(){function a(a,b){if(this.container="string"==typeof a?document.querySelector(a):a,!this.container||!this.container.offsetWidth)throw"JpegCamera: invalid container";this.container.innerHTML="",this.options=this._extend({},this.constructor.DefaultOptions,b),this._engine_init()}return a.DefaultOptions={shutter_url:"/jpeg_camera/shutter.mp3",swf_url:"/jpeg_camera/jpeg_camera.swf",on_debug:function(a){return console&&console.log?console.log("JpegCamera: "+a):void 0},quality:.9,shutter:!0,mirror:!1,timeout:0,retry_success:!1},a.prototype.ready=function(a){return this.options.on_ready=a,this.options.on_ready&&this._is_ready&&this.options.on_ready.call(this),this},a.prototype._is_ready=!1,a.prototype.error=function(a){return this.options.on_error=a,this.options.on_error&&this._error_occured&&this.options.on_error.call(this,this._error_occured),this},a.prototype._error_occured=!1,a.prototype.capture=function(a){var b,d;return null==a&&(a={}),b=new c(this,a),this._snapshots[b.id]=b,d=b._options(),d.shutter&&this._engine_play_shutter_sound(),this._engine_capture(b,d.mirror,d.quality),b},a.prototype._snapshots={},a.prototype.show_stream=function(){return this._engine_show_stream(),this._displayed_snapshot=null,this},a.prototype.discard_all=function(){var a,b,c;this._displayed_snapshot&&this.show_stream(),c=this._snapshots;for(a in c)b=c[a],this._engine_discard(b),b._discarded=!0;return this._snapshots={},this},a.prototype._extend=function(a){var b,c,d,e,f,g;for(d=Array.prototype.slice.call(arguments,1),f=0,g=d.length;g>f;f++)if(c=d[f])for(b in c)e=c[b],a[b]=e;return a},a.prototype._debug=function(a){return this.options.on_debug?this.options.on_debug.call(this,a):void 0},a.prototype._view_width=function(){return parseInt(this.container.offsetWidth,10)},a.prototype._view_height=function(){return parseInt(this.container.offsetHeight,10)},a.prototype._display=function(a){return this._engine_display(a),this._displayed_snapshot=a},a.prototype._displayed_snapshot=null,a.prototype._upload=function(a,b,c,d){return this._engine_upload(a,b,c,d)},a.prototype._discard=function(a){return this._displayed_snapshot===a&&this.show_stream(),this._engine_discard(a),a._discarded=!0,delete this._snapshots[a.id]},a.prototype._prepared=function(){return this._is_ready=!0,this.options.on_ready?this.options.on_ready.call(this):void 0},a.prototype._got_error=function(a){return this._debug("Error - "+a),this._error_occured=a,this.options.on_error?this.options.on_error.call(this,this._error_occured):void 0},a}(),navigator.getUserMedia||(navigator.getUserMedia=navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia),navigator.getUserMedia&&(b=function(a){function b(){return d=b.__super__.constructor.apply(this,arguments)}return f(b,a),b.prototype._engine_init=function(){var a,b,c,d;return this._debug("Using HTML5 engine"),this.internal_container=document.createElement("div"),this.internal_container.style.width="100%",this.internal_container.style.height="100%",this.internal_container.style.position="relative",this.container.appendChild(this.internal_container),d=Math.floor(.2*this._view_height()),b=Math.floor(.2*this._view_width()),this.message=document.createElement("div"),this.message["class"]="message",this.message.style.width="100%",this.message.style.height="100%",this._add_prefixed_style(this.message,"boxSizing","border-box"),this.message.style.overflow="hidden",this.message.style.textAlign="center",this.message.style.paddingTop=""+d+"px",this.message.style.paddingBottom=""+d+"px",this.message.style.paddingLeft=""+b+"px",this.message.style.paddingRight=""+b+"px",this.message.style.position="absolute",this.message.style.zIndex=3,this.message.innerHTML="Please allow camera access when prompted by the browser.",this.internal_container.appendChild(this.message),this.video_container=document.createElement("div"),this.video_container.style.width=""+this._view_width()+"px",this.video_container.style.height=""+this._view_height()+"px",this.video_container.style.overflow="hidden",this.video_container.style.position="absolute",this.video_container.style.zIndex=1,this.internal_container.appendChild(this.video_container),this.video=document.createElement("video"),this.video.autoplay=!0,this._add_prefixed_style(this.video,"transform","scalex(-1.0)"),window.AudioContext||(window.AudioContext=window.webkitAudioContext),window.AudioContext&&this._load_shutter_sound(),a={video:{optional:[{minWidth:1280},{minWidth:640},{minWidth:480},{minWidth:360}]}},c=this,navigator.getUserMedia(a,function(a){return c._remove_message(),c.video.src=window.URL?URL.createObjectURL(a):a,c._wait_for_video_ready()},function(a){var b,d,e;b=a.code;for(d in a)if(e=a[d],"code"!==d)return c._got_error(d),void 0;return c._got_error("UNKNOWN ERROR")})},b.prototype._engine_play_shutter_sound=function(){var a;if(this.shutter_buffer)return a=this.audio_context.createBufferSource(),a.buffer=this.shutter_buffer,a.connect(this.audio_context.destination),a.start(0)},b.prototype._engine_capture=function(a,b,c){var d,e,f;return f=this._get_capture_crop(),d=document.createElement("canvas"),d.width=f.width,d.height=f.height,e=d.getContext("2d"),e.drawImage(this.video,f.x_offset,f.y_offset,f.width,f.height,0,0,f.width,f.height),a._canvas=d,a._mirror=b,a._quality=c},b.prototype._engine_display=function(a){return this.displayed_canvas&&this.internal_container.removeChild(this.displayed_canvas),this.displayed_canvas=a._canvas,this.displayed_canvas.style.width=""+this._view_width()+"px",this.displayed_canvas.style.height=""+this._view_height()+"px",this.displayed_canvas.style.top=0,this.displayed_canvas.style.left=0,this.displayed_canvas.style.position="absolute",this.displayed_canvas.style.zIndex=2,this._add_prefixed_style(this.displayed_canvas,"transform","scalex(-1.0)"),this.internal_container.appendChild(this.displayed_canvas)},b.prototype._engine_discard=function(a){return a._xhr&&a._xhr.abort(),delete a._xhr,delete a._canvas,delete a._jpeg_blob},b.prototype._engine_show_stream=function(){return this.displayed_canvas&&(this.internal_container.removeChild(this.displayed_canvas),this.displayed_canvas=null),this.video_container.style.display="block"},b.prototype._engine_upload=function(a,b,c,d){var e,f,g,h,i;return h=this,a._jpeg_blob?(this._debug("Uploading the file"),g=function(b){return delete a._xhr,a._status=b.target.status,a._response=b.target.responseText,a._status>=200&&a._status<300?a._upload_done():(a._error_message=b.target.statusText||"Unknown error",a._upload_fail())},i=new XMLHttpRequest,i.open("POST",b),i.timeout=d,c&&i.setRequestHeader("X-CSRF-Token",c),i.onload=g,i.onerror=g,i.onabort=g,i.send(a._jpeg_blob),a._xhr=i):(this._debug("Generating JPEG file"),a._mirror?(e=document.createElement("canvas"),e.width=a._canvas.width,e.height=a._canvas.height,f=e.getContext("2d"),f.setTransform(1,0,0,1,0,0),f.translate(e.width,0),f.scale(-1,1),f.drawImage(a._canvas,0,0)):e=a._canvas,e.toBlob(function(e){return a._jpeg_blob=e,h._engine_upload(a,b,c,d)},"image/jpeg",this.quality))},b.prototype._remove_message=function(){return this.message.style.display="none"},b.prototype._load_shutter_sound=function(){var a,b;if(!this.audio_context)return this.audio_context=new AudioContext,a=new XMLHttpRequest,a.open("GET",this.options.shutter_url,!0),a.responseType="arraybuffer",b=this,a.onload=function(){return b.audio_context.decodeAudioData(a.response,function(a){return b.shutter_buffer=a})},a.send()},b.prototype._wait_for_video_ready=function(){var a,b,c,d;return d=parseInt(this.video.videoWidth),c=parseInt(this.video.videoHeight),d>0&&c>0?(this.video_container.appendChild(this.video),this.video_width=d,this.video_height=c,this._debug("Camera resolution "+this.video_width+"x"+this.video_height+"px"),a=this._get_video_crop(),this.video.style.position="relative",this.video.style.width=""+a.width+"px",this.video.style.height=""+a.height+"px",this.video.style.left=""+a.x_offset+"px",this.video.style.top=""+a.y_offset+"px",this._prepared()):this._status_checks_count>100?this._got_error("Camera failed to initialize in 10 seconds"):(this._status_checks_count++,b=this,setTimeout(function(){return b._wait_for_video_ready()},100))},b.prototype._status_checks_count=0,b.prototype._add_prefixed_style=function(a,b,c){var d;return d=b.charAt(0).toUpperCase()+b.slice(1),a.style[b]=c,a.style["Webkit"+d]=c,a.style["Moz"+d]=c,a.style["ms"+d]=c,a.style["O"+d]=c},b.prototype._get_video_crop=function(){var a,b,c,d,e,f,g;return g=this._view_width(),e=this._view_height(),c=this.video_width/this.video_height,f=g/e,c>=f?(this._debug("Filling height"),d=e/this.video_height,b=Math.round(this.video_width*d),{width:b,height:e,x_offset:-Math.floor((b-g)/2),y_offset:0}):(this._debug("Filling width"),d=g/this.video_width,a=Math.round(this.video_height*d),{width:g,height:a,x_offset:0,y_offset:-Math.floor((a-e)/2)})},b.prototype._get_capture_crop=function(){var a,b,c,d,e,f;return f=this._view_width(),d=this._view_height(),c=this.video_width/this.video_height,e=f/d,c>=e?(b=Math.round(this.video_height*e),{width:b,height:this.video_height,x_offset:Math.floor((this.video_width-b)/2),y_offset:0}):(a=Math.round(this.video_width/e),{width:this.video_width,height:a,x_offset:0,y_offset:Math.floor((this.video_height-a)/2)})},b}(a),window.JpegCamera=b),c=function(){function a(a,b){this.camera=a,this.options=b,this.id=this.constructor._next_snapshot_id++}return a._next_snapshot_id=1,a.prototype._discarded=!1,a.prototype.show=function(){return this._discarded&&raise("discarded snapshot cannot be used"),this.camera._display(this),this},a.prototype.hide=function(){return this.camera.displayed_snapshot()===this&&this.camera.show_stream(),this},a.prototype.upload=function(a){var b;if(null==a&&(a={}),this._discarded&&raise("discarded snapshot cannot be used"),this._uploading)return this.camera._debug("Upload already in progress"),void 0;if(this._uploading=!0,this._retry=1,this._upload_options=a,b=this._options(),!b.api_url)throw this.camera._debug("Snapshot#upload called without valid api_url"),"Snapshot#upload called without valid api_url";return this._start_upload(b),this},a.prototype._upload_options={},a.prototype._uploading=!1,a.prototype._retry=1,a.prototype.done=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_done=a,b=this._options(),b.on_upload_done&&this._done&&b.on_upload_done.call(this,this._response),this},a.prototype._done=!1,a.prototype._response=null,a.prototype.fail=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_fail=a,b=this._options(),b.on_upload_fail&&this._fail&&b.on_upload_fail.call(this,this._status,this._error_message,this._response),this},a.prototype._fail=!1,a.prototype._status=null,a.prototype._error_message=null,a.prototype.discard=function(){return this.camera._discard(this),void 0},a.prototype._options=function(){return this.camera._extend({},this.camera.options,this.options,this._upload_options)},a.prototype._start_upload=function(a){var b;return b="string"==typeof a.csrf_token&&a.csrf_token.length>0?a.csrf_token:null,this._done=!1,this._response=null,this._fail=!1,this._status=null,this._error_message=null,this.camera._upload(this,a.api_url,b,a.timeout)},a.prototype._upload_done=function(){var a,b,c,d;return this.camera._debug("Upload completed with status "+this._status),this._done=!0,a=this._options(),c=a.retry_success&&a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_done?a.on_upload_done.call(this,this._response):void 0)},a.prototype._upload_fail=function(){var a,b,c,d;return this.camera._debug("Upload failed with status "+this._status),this._fail=!0,a=this._options(),c=a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_fail?a.on_upload_fail.call(this,this._status,this._error_message,this._response):void 0)},a}()}.call(this);
|
4
|
+
!function(){var a,b,c,d,e,f={}.hasOwnProperty,g=function(a,b){function c(){this.constructor=a}for(var d in b)f.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};a=function(){function a(a,b){if("string"==typeof a&&(a=document.getElementById(a.replace("#",""))),!a||!a.offsetWidth)throw"JpegCamera: invalid container";a.innerHTML="",this.container=document.createElement("div"),this.container.style.width="100%",this.container.style.height="100%",this.container.style.position="relative",a.appendChild(this.container),this.options=this._extend({},this.constructor.DefaultOptions,b),this._engine_init()}return a.DefaultOptions={shutter_url:"/jpeg_camera/shutter.mp3",swf_url:"/jpeg_camera/jpeg_camera.swf",on_debug:function(a){return console&&console.log?console.log("JpegCamera: "+a):void 0},quality:.9,shutter:!0,mirror:!1,timeout:0,retry_success:!1},a._canvas_supported=!!document.createElement("canvas").getContext,a.canvas_supported=function(){return this._canvas_supported},a.prototype.ready=function(a){return this.options.on_ready=a,this.options.on_ready&&this._is_ready&&this.options.on_ready.call(this),this},a.prototype._is_ready=!1,a.prototype.error=function(a){return this.options.on_error=a,this.options.on_error&&this._error_occured&&this.options.on_error.call(this,this._error_occured),this},a.prototype._error_occured=!1,a.StatsCaptureScale=.2,a.prototype.get_stats=function(b){var d,e;return d=new c(this,{}),this._engine_capture(d,!1,.1,a.StatsCaptureScale),e=this,d.get_stats(function(a){return b.call(e,a)})},a.prototype.capture=function(a){var b,d;return null==a&&(a={}),b=new c(this,a),this._snapshots[b.id]=b,d=b._options(),d.shutter&&this._engine_play_shutter_sound(),this._engine_capture(b,d.mirror,d.quality,1),b},a.prototype._snapshots={},a.prototype.show_stream=function(){return this._engine_show_stream(),this._displayed_snapshot=null,this},a.prototype.discard_all=function(){var a,b,c;this._displayed_snapshot&&this.show_stream(),c=this._snapshots;for(a in c)b=c[a],this._engine_discard(b),b._discarded=!0;return this._snapshots={},this},a.prototype._extend=function(a){var b,c,d,e,f,g;for(d=Array.prototype.slice.call(arguments,1),f=0,g=d.length;g>f;f++)if(c=d[f])for(b in c)e=c[b],a[b]=e;return a},a.prototype._debug=function(a){return this.options.on_debug?this.options.on_debug.call(this,a):void 0},a.prototype._view_width=function(){return parseInt(this.container.offsetWidth,10)},a.prototype._view_height=function(){return parseInt(this.container.offsetHeight,10)},a.prototype._display=function(a){return this._engine_display(a),this._displayed_snapshot=a},a.prototype._displayed_snapshot=null,a.prototype._discard=function(a){return this._displayed_snapshot===a&&this.show_stream(),this._engine_discard(a),a._discarded=!0,delete this._snapshots[a.id]},a.prototype._prepared=function(){var a;return a=this,setTimeout(function(){return a._wait_until_stream_looks_ok(!0)},1)},a.prototype._wait_until_stream_looks_ok=function(a){return this.get_stats(function(b){var c;return b.std>2?(this._debug("Stream mean gray value = "+b.mean+" standard deviation = "+b.std),this._debug("Camera is ready"),this._is_ready=!0,this.options.on_ready?this.options.on_ready.call(this):void 0):(a&&this._debug("Stream mean gray value = "+b.mean+" standard deviation = "+b.std),c=this,setTimeout(function(){return c._wait_until_stream_looks_ok(!1)},100))})},a.prototype._got_error=function(a){return this._debug("Error - "+a),this._error_occured=a,this.options.on_error?this.options.on_error.call(this,this._error_occured):void 0},a.prototype._block_element_access=function(){return this._overlay=document.createElement("div"),this._overlay.style.width="100%",this._overlay.style.height="100%",this._overlay.style.position="absolute",this._overlay.style.top=0,this._overlay.style.left=0,this._overlay.style.zIndex=2,this.container.appendChild(this._overlay)},a.prototype._overlay=null,a._add_prefixed_style=function(a,b,c){var d;return d=b.charAt(0).toUpperCase()+b.slice(1),a.style[b]=c,a.style["Webkit"+d]=c,a.style["Moz"+d]=c,a.style["ms"+d]=c,a.style["O"+d]=c},a}(),navigator.getUserMedia||(navigator.getUserMedia=navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia),d=function(){var a;if(a=document.createElement("canvas"),a.getContext&&!a.toBlob)throw"JpegCamera: Canvas-to-Blob is not loaded"},navigator.getUserMedia&&(d(),b=function(b){function c(){return e=c.__super__.constructor.apply(this,arguments)}return g(c,b),c.prototype._engine_init=function(){var b,c,d,e,f,g,h;this._debug("Using HTML5 engine"),h=Math.floor(.2*this._view_height()),e=Math.floor(.2*this._view_width()),this.message=document.createElement("div"),this.message["class"]="message",this.message.style.width="100%",this.message.style.height="100%",a._add_prefixed_style(this.message,"boxSizing","border-box"),this.message.style.overflow="hidden",this.message.style.textAlign="center",this.message.style.paddingTop=""+h+"px",this.message.style.paddingBottom=""+h+"px",this.message.style.paddingLeft=""+e+"px",this.message.style.paddingRight=""+e+"px",this.message.style.position="absolute",this.message.style.zIndex=3,this.message.innerHTML="Please allow camera access when prompted by the browser.<br><br>Look for camera icon around your address bar.",this.container.appendChild(this.message),this.video_container=document.createElement("div"),this.video_container.style.width=""+this._view_width()+"px",this.video_container.style.height=""+this._view_height()+"px",this.video_container.style.overflow="hidden",this.video_container.style.position="absolute",this.video_container.style.zIndex=1,this.container.appendChild(this.video_container),this.video=document.createElement("video"),this.video.autoplay=!0,a._add_prefixed_style(this.video,"transform","scalex(-1.0)"),window.AudioContext||(window.AudioContext=window.webkitAudioContext),window.AudioContext&&this._load_shutter_sound(),d={video:{optional:[{minWidth:1280},{minWidth:640},{minWidth:480},{minWidth:360}]}},g=this,f=function(a){return g._remove_message(),g.video.src=window.URL?URL.createObjectURL(a):a,g._block_element_access(),g._wait_for_video_ready()},c=function(a){var b,c,d;g.message.innerHTML='<span style="color: red;">You have denied camera access.</span><br><br>Look for camera icon around your address bar to change your decision.',b=a.code;for(c in a)if(d=a[c],"code"!==c)return g._got_error(c),void 0;return g._got_error("UNKNOWN ERROR")};try{return navigator.getUserMedia(d,f,c)}catch(i){return b=i,navigator.getUserMedia("video",f,c)}},c.prototype._engine_play_shutter_sound=function(){var a;if(this.shutter_buffer)return a=this.audio_context.createBufferSource(),a.buffer=this.shutter_buffer,a.connect(this.audio_context.destination),a.start(0)},c.prototype._engine_capture=function(a,b,c,d){var e,f,g;return g=this._get_capture_crop(),e=document.createElement("canvas"),e.width=Math.round(g.width*d),e.height=Math.round(g.height*d),f=e.getContext("2d"),f.drawImage(this.video,g.x_offset,g.y_offset,g.width,g.height,0,0,Math.round(g.width*d),Math.round(g.height*d)),a._canvas=e,a._mirror=b,a._quality=c},c.prototype._engine_display=function(b){return this.displayed_canvas&&this.container.removeChild(this.displayed_canvas),this.displayed_canvas=b._canvas,this.displayed_canvas.style.width=""+this._view_width()+"px",this.displayed_canvas.style.height=""+this._view_height()+"px",this.displayed_canvas.style.top=0,this.displayed_canvas.style.left=0,this.displayed_canvas.style.position="absolute",this.displayed_canvas.style.zIndex=2,a._add_prefixed_style(this.displayed_canvas,"transform","scalex(-1.0)"),this.container.appendChild(this.displayed_canvas)},c.prototype._engine_get_canvas=function(a){var b,c;return b=document.createElement("canvas"),b.width=a._canvas.width,b.height=a._canvas.height,c=b.getContext("2d"),c.drawImage(a._canvas,0,0),b},c.prototype._engine_get_image_data=function(a){var b,c;return b=a._canvas,c=b.getContext("2d"),c.getImageData(0,0,b.width,b.height)},c.prototype._engine_discard=function(a){return a._xhr&&a._xhr.abort(),delete a._xhr,delete a._canvas,delete a._jpeg_blob},c.prototype._engine_show_stream=function(){return this.displayed_canvas&&(this.container.removeChild(this.displayed_canvas),this.displayed_canvas=null),this.video_container.style.display="block"},c.prototype._engine_upload=function(a,b,c,d){var e,f,g,h,i;return h=this,a._jpeg_blob?(this._debug("Uploading the file"),g=function(b){return delete a._xhr,a._status=b.target.status,a._response=b.target.responseText,a._status>=200&&a._status<300?a._upload_done():(a._error_message=b.target.statusText||"Unknown error",a._upload_fail())},i=new XMLHttpRequest,i.open("POST",b),i.timeout=d,c&&i.setRequestHeader("X-CSRF-Token",c),i.onload=g,i.onerror=g,i.onabort=g,i.send(a._jpeg_blob),a._xhr=i):(this._debug("Generating JPEG file"),a._mirror?(e=document.createElement("canvas"),e.width=a._canvas.width,e.height=a._canvas.height,f=e.getContext("2d"),f.setTransform(1,0,0,1,0,0),f.translate(e.width,0),f.scale(-1,1),f.drawImage(a._canvas,0,0)):e=a._canvas,e.toBlob(function(e){return a._jpeg_blob=e,h._engine_upload(a,b,c,d)},"image/jpeg",this.quality))},c.prototype._remove_message=function(){return this.message.style.display="none"},c.prototype._load_shutter_sound=function(){var a,b;if(!this.audio_context)return this.audio_context=new AudioContext,a=new XMLHttpRequest,a.open("GET",this.options.shutter_url,!0),a.responseType="arraybuffer",b=this,a.onload=function(){return b.audio_context.decodeAudioData(a.response,function(a){return b.shutter_buffer=a})},a.send()},c.prototype._wait_for_video_ready=function(){var a,b,c,d;return d=parseInt(this.video.videoWidth),c=parseInt(this.video.videoHeight),d>0&&c>0?(this.video_container.appendChild(this.video),this.video_width=d,this.video_height=c,this._debug("Camera resolution "+this.video_width+"x"+this.video_height+"px"),a=this._get_video_crop(),this.video.style.position="relative",this.video.style.width=""+a.width+"px",this.video.style.height=""+a.height+"px",this.video.style.left=""+a.x_offset+"px",this.video.style.top=""+a.y_offset+"px",this._prepared()):this._status_checks_count>100?this._got_error("Camera failed to initialize in 10 seconds"):(this._status_checks_count++,b=this,setTimeout(function(){return b._wait_for_video_ready()},100))},c.prototype._status_checks_count=0,c.prototype._get_video_crop=function(){var a,b,c,d,e,f,g;return g=this._view_width(),e=this._view_height(),c=this.video_width/this.video_height,f=g/e,c>=f?(this._debug("Filling height"),d=e/this.video_height,b=Math.round(this.video_width*d),{width:b,height:e,x_offset:-Math.floor((b-g)/2),y_offset:0}):(this._debug("Filling width"),d=g/this.video_width,a=Math.round(this.video_height*d),{width:g,height:a,x_offset:0,y_offset:-Math.floor((a-e)/2)})},c.prototype._get_capture_crop=function(){var a,b,c,d,e,f;return f=this._view_width(),d=this._view_height(),c=this.video_width/this.video_height,e=f/d,c>=e?(b=Math.round(this.video_height*e),{width:b,height:this.video_height,x_offset:Math.floor((this.video_width-b)/2),y_offset:0}):(a=Math.round(this.video_width/e),{width:this.video_width,height:a,x_offset:0,y_offset:Math.floor((this.video_height-a)/2)})},c}(a),window.JpegCamera=b),c=function(){function b(a,b){this.camera=a,this.options=b,this.id=this.constructor._next_snapshot_id++}return b._next_snapshot_id=1,b.prototype._discarded=!1,b.prototype.show=function(){return this._discarded&&raise("discarded snapshot cannot be used"),this.camera._display(this),this},b.prototype.hide=function(){return this.camera.displayed_snapshot()===this&&this.camera.show_stream(),this},b.prototype.get_stats=function(a){return this._discarded&&raise("discarded snapshot cannot be used"),this.get_image_data(function(b){return this._get_stats(b,a)})},b.prototype.get_canvas=function(b){var c;return this._discarded&&raise("discarded snapshot cannot be used"),!a._canvas_supported,c=this,setTimeout(function(){return c._extra_canvas||(c._extra_canvas=c.camera._engine_get_canvas(c)),a._add_prefixed_style(c._extra_canvas,"transform","scalex(-1.0)"),b.call(c,c._extra_canvas)},10),!0},b.prototype._extra_canvas=null,b.prototype.get_image_data=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),b=this,setTimeout(function(){return b._image_data||(b._image_data=b.camera._engine_get_image_data(b)),a.call(b,b._image_data)},5)},b.prototype._image_data=null,b.prototype.upload=function(a){var b;if(null==a&&(a={}),this._discarded&&raise("discarded snapshot cannot be used"),this._uploading)return this.camera._debug("Upload already in progress"),void 0;if(this._uploading=!0,this._retry=1,this._upload_options=a,b=this._options(),!b.api_url)throw this.camera._debug("Snapshot#upload called without valid api_url"),"Snapshot#upload called without valid api_url";return this._start_upload(b),this},b.prototype._upload_options={},b.prototype._uploading=!1,b.prototype._retry=1,b.prototype.done=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_done=a,b=this._options(),b.on_upload_done&&this._done&&b.on_upload_done.call(this,this._response),this},b.prototype._done=!1,b.prototype._response=null,b.prototype.fail=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_fail=a,b=this._options(),b.on_upload_fail&&this._fail&&b.on_upload_fail.call(this,this._status,this._error_message,this._response),this},b.prototype._fail=!1,b.prototype._status=null,b.prototype._error_message=null,b.prototype.discard=function(){return this.camera._discard(this),void 0},b.prototype._options=function(){return this.camera._extend({},this.camera.options,this.options,this._upload_options)},b.prototype._start_upload=function(a){var b;return b="string"==typeof a.csrf_token&&a.csrf_token.length>0?a.csrf_token:null,this._done=!1,this._response=null,this._fail=!1,this._status=null,this._error_message=null,this.camera._engine_upload(this,a.api_url,b,a.timeout)},b.prototype._get_stats=function(a,b){var c,d,e,f,g,h,i,j,k,l,m;if(!this._stats){for(h=a.width*a.height,i=0,d=new Array(h),e=k=0;h>k;e=k+=1)f=4*e,c=.2126*a.data[f+0]+.7152*a.data[f+1]+.0722*a.data[f+2],c=Math.round(c),i+=c,d[e]=c;for(g=Math.round(i/h),j=0,l=0,m=d.length;m>l;l++)c=d[l],j+=Math.pow(c-g,2);this._stats={mean:g,std:Math.round(Math.sqrt(j/h))}}return b.call(this,this._stats)},b.prototype._stats=null,b.prototype._upload_done=function(){var a,b,c,d;return this.camera._debug("Upload completed with status "+this._status),this._done=!0,a=this._options(),c=a.retry_success&&a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_done?a.on_upload_done.call(this,this._response):void 0)},b.prototype._upload_fail=function(){var a,b,c,d;return this.camera._debug("Upload failed with status "+this._status),this._fail=!0,a=this._options(),c=a.retry_if&&a.retry_if.call(this,this._status,this._error_message,this._response,this._retry),!0===c&&(c=0),"number"==typeof c?(this._retry++,c>0?(b=parseInt(c),this.camera._debug("Will retry the upload in "+b+"ms (attempt #"+this._retry+")"),d=this,setTimeout(function(){return d._start_upload(a)},b)):(this.camera._debug("Will retry the upload immediately (attempt #"+this._retry+")"),this._start_upload(a))):(this._uploading=!1,a.on_upload_fail?a.on_upload_fail.call(this,this._status,this._error_message,this._response):void 0)},b}()}.call(this);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jpeg_camera
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Wróbel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|