@capturebridge/sdk 0.9.0 → 0.10.0
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.
- package/CHANGELOG.md +14 -0
- package/Common.js +25 -0
- package/ICAO.js +19 -7
- package/IFace.js +6 -50
- package/ImageSource.js +110 -0
- package/Version.js +1 -1
- package/examples/canon.html +1 -47
- package/examples/canon.js +44 -0
- package/examples/canon_getframe.html +1 -49
- package/examples/canon_getframe.js +46 -0
- package/examples/canon_lan.html +1 -49
- package/examples/canon_lan.js +46 -0
- package/examples/canon_minimal.html +1 -31
- package/examples/canon_minimal.js +27 -0
- package/examples/empty.jpg +0 -0
- package/examples/icao.html +7 -0
- package/examples/icao.jpg +0 -0
- package/examples/icao.js +80 -0
- package/examples/mockcamera.html +2 -43
- package/examples/mockcamera.js +39 -0
- package/examples/mockcamera_getframe.html +1 -44
- package/examples/mockcamera_getframe.js +40 -0
- package/examples/mockcamera_minimal.html +1 -25
- package/examples/mockcamera_minimal.js +21 -0
- package/examples/verifone_signature.html +7 -0
- package/examples/verifone_signature.js +14 -0
- package/examples/windows_scanner_minimal.html +1 -25
- package/examples/windows_scanner_minimal.js +19 -0
- package/package.json +1 -1
- package/examples/verifone_minimal.html +0 -23
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.10.0] - 2024-06-17
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Introduced breaking changes to the structure of the object returned from
|
|
13
|
+
`ICAO.check()`
|
|
14
|
+
- `ICAO` class will default to use the `capture_verify_iface` plugin if no
|
|
15
|
+
plugin is provided to the constructor.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Coordinates of the cropped photo are now returned from `ICAO.check()` if a face
|
|
20
|
+
was found.
|
|
21
|
+
|
|
8
22
|
## [0.9.0] - 2024-06-06
|
|
9
23
|
|
|
10
24
|
### Added
|
package/Common.js
CHANGED
|
@@ -133,6 +133,31 @@ export const DATAURL_JPEG = 'data:image/jpeg;base64,'
|
|
|
133
133
|
*/
|
|
134
134
|
export const DATAURL_PNG = 'data:image/png;base64,'
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* @summary For a given base64 string, convert it to the appropriate Data URL
|
|
138
|
+
* @constant
|
|
139
|
+
* @type {string}
|
|
140
|
+
*/
|
|
141
|
+
export const base64ToDataURL = base64 => {
|
|
142
|
+
const magicBytes = atob(base64.slice(0, 6))
|
|
143
|
+
const byteArray = new Uint8Array(magicBytes.length)
|
|
144
|
+
for (let i = 0; i < magicBytes.length; i++) {
|
|
145
|
+
byteArray[i] = magicBytes.charCodeAt(i)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Check for JPEG magic number (FF D8 FF)
|
|
149
|
+
if (byteArray[0] === 0xFF && byteArray[1] === 0xD8 && byteArray[2] === 0xFF) {
|
|
150
|
+
return DATAURL_JPEG + base64
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check for PNG magic number (89 50 4E 47)
|
|
154
|
+
if (byteArray[0] === 0x89 && byteArray[1] === 0x50 && byteArray[2] === 0x4E && byteArray[3] === 0x47) {
|
|
155
|
+
return DATAURL_PNG + base64
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
throw new Error('Unknown image format provided in Base64 string')
|
|
159
|
+
}
|
|
160
|
+
|
|
136
161
|
/**
|
|
137
162
|
* An Async/Await version of
|
|
138
163
|
* {@link https://developer.mozilla.org/en-US/docs/Web/API/setTimeout|setTimeout}
|
package/ICAO.js
CHANGED
|
@@ -5,7 +5,7 @@ import { BASE_URL } from './Common.js'
|
|
|
5
5
|
* ICAO
|
|
6
6
|
* @classdesc Class for invoking ICAO checks on an image
|
|
7
7
|
* @extends Plugin
|
|
8
|
-
* @see {@link
|
|
8
|
+
* @see {@link IFace}
|
|
9
9
|
*/
|
|
10
10
|
class ICAO extends Plugin {
|
|
11
11
|
/**
|
|
@@ -14,18 +14,19 @@ class ICAO extends Plugin {
|
|
|
14
14
|
* @param {string} [baseURL] - Protocol, domain, and port for the service.
|
|
15
15
|
* @param {string|object} plugin - The ID of the desired plugin to use for
|
|
16
16
|
* this instance or an existing Plugin object. The plugin must support the
|
|
17
|
-
*
|
|
17
|
+
* `icao` method. Defaults to the `capture_verify_iface` plugin.
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
|
-
* const icao = new ICAO(
|
|
20
|
+
* const icao = new ICAO()
|
|
21
21
|
*/
|
|
22
|
-
constructor (plugin, baseUrl = BASE_URL) {
|
|
22
|
+
constructor (plugin = 'capture_verify_iface', baseUrl = BASE_URL) {
|
|
23
23
|
super(plugin, baseUrl)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Check the ICAO compliance of an image
|
|
28
|
-
* @param {string} image - A base64 encoded image
|
|
28
|
+
* @param {string|ImageSource} image - A string containing base64 encoded image
|
|
29
|
+
* data or an ImageSource object.
|
|
29
30
|
*
|
|
30
31
|
* @param {string|bool} [crop] - If falsy image will not be cropped, otherwise
|
|
31
32
|
* the value will be interpreted as the preferred crop method which will vary
|
|
@@ -40,7 +41,7 @@ class ICAO extends Plugin {
|
|
|
40
41
|
* // returned image
|
|
41
42
|
* const camera = new CanonCamera()
|
|
42
43
|
* const photo = await camera.takePhoto('base64')
|
|
43
|
-
* const icao = new ICAO(
|
|
44
|
+
* const icao = new ICAO()
|
|
44
45
|
* const results = await icao.check(photo)
|
|
45
46
|
* const img = document.createElement('img')
|
|
46
47
|
* img.src = 'data:image/jpeg;base64,' + results.cropped
|
|
@@ -48,8 +49,19 @@ class ICAO extends Plugin {
|
|
|
48
49
|
* document.body.appendChild(img)
|
|
49
50
|
*/
|
|
50
51
|
async check (image, cropMethod = false) {
|
|
52
|
+
let imageData
|
|
53
|
+
|
|
54
|
+
// If this is an ImageSource object fetch it's image data
|
|
55
|
+
if (typeof image === 'object' && image.constructor.name === 'ImageSource') {
|
|
56
|
+
imageData = await image.data()
|
|
57
|
+
} else if (typeof image === 'string') {
|
|
58
|
+
imageData = image
|
|
59
|
+
} else {
|
|
60
|
+
throw new Error('Unexpected value provided for image parameter')
|
|
61
|
+
}
|
|
62
|
+
|
|
51
63
|
const body = {
|
|
52
|
-
base64:
|
|
64
|
+
base64: imageData,
|
|
53
65
|
crop: Boolean(cropMethod),
|
|
54
66
|
crop_method: cropMethod || undefined
|
|
55
67
|
}
|
package/IFace.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import ICAO from './ICAO.js'
|
|
6
|
-
import
|
|
6
|
+
import ImageSource from './ImageSource.js'
|
|
7
|
+
import { BASE_URL } from './Common.js'
|
|
7
8
|
|
|
8
9
|
// This is not exported as we may eventually detect this from the plugin
|
|
9
10
|
// See: Iface.matchModes()
|
|
@@ -15,10 +16,7 @@ const VALID_MODES = ['accurate', 'balanced', 'fast', 'accurate_server']
|
|
|
15
16
|
*
|
|
16
17
|
* @see {@link IFace}
|
|
17
18
|
*/
|
|
18
|
-
export class Probe {
|
|
19
|
-
source
|
|
20
|
-
url
|
|
21
|
-
imageData
|
|
19
|
+
export class Probe extends ImageSource {
|
|
22
20
|
/**
|
|
23
21
|
* Instantiate an IFace Probe
|
|
24
22
|
* @constructor
|
|
@@ -30,59 +28,17 @@ export class Probe {
|
|
|
30
28
|
* const candidate = new Candidate('/person/123.jpg', '123', 'url')
|
|
31
29
|
*/
|
|
32
30
|
constructor (source, type = 'base64') {
|
|
33
|
-
|
|
34
|
-
// If the source is typeof object and/or type=object we should do some duck
|
|
35
|
-
// typing and accept any of...
|
|
36
|
-
// - The result of an ICAO check that contains a cropped image
|
|
37
|
-
// - An Image tag (fetch the source)
|
|
38
|
-
// - A Blob
|
|
39
|
-
// - An Array Buffer
|
|
40
|
-
// - An object that has a fullCapture method (call function in .data())
|
|
41
|
-
switch (type) {
|
|
42
|
-
case 'url':
|
|
43
|
-
this.url = source
|
|
44
|
-
break
|
|
45
|
-
case 'base64':
|
|
46
|
-
this.imageData = source
|
|
47
|
-
break
|
|
48
|
-
case 'dataurl':
|
|
49
|
-
this.imageData = source.split(',')[1]
|
|
50
|
-
break
|
|
51
|
-
case undefined:
|
|
52
|
-
case null:
|
|
53
|
-
default:
|
|
54
|
-
throw new Error('Invalid image source type provided')
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Fetch the image data and base64 encode it
|
|
60
|
-
* @async
|
|
61
|
-
* @example
|
|
62
|
-
* const probe = new Probe("/img/photo.jpg")
|
|
63
|
-
* await probe.data()
|
|
64
|
-
* console.log(probe.imageData)
|
|
65
|
-
*/
|
|
66
|
-
async data () {
|
|
67
|
-
if (!this.imageData) {
|
|
68
|
-
const response = await fetch(this.url)
|
|
69
|
-
const blob = await response.blob()
|
|
70
|
-
this.imageData = await blobToBase64(blob)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
toJSON () {
|
|
75
|
-
return this.imageData
|
|
31
|
+
super(source, type)
|
|
76
32
|
}
|
|
77
33
|
}
|
|
78
34
|
|
|
79
35
|
/**
|
|
80
36
|
* Candidate
|
|
81
37
|
* @classdesc Candidate Class for Innovatrics IFace SDK
|
|
82
|
-
* @extends
|
|
38
|
+
* @extends ImageSource
|
|
83
39
|
* @see {@link IFace}
|
|
84
40
|
*/
|
|
85
|
-
export class Candidate extends
|
|
41
|
+
export class Candidate extends ImageSource {
|
|
86
42
|
id
|
|
87
43
|
|
|
88
44
|
// TODO: Support setting different modes on individual candidates
|
package/ImageSource.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { blobToBase64, base64ToDataURL, checkResponse } from './Common.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ImageSource
|
|
5
|
+
* @classdesc Class to handle loading various image formats
|
|
6
|
+
*
|
|
7
|
+
* @see {@link Probe}
|
|
8
|
+
*/
|
|
9
|
+
export class ImageSource {
|
|
10
|
+
source
|
|
11
|
+
url
|
|
12
|
+
imageData
|
|
13
|
+
type
|
|
14
|
+
/**
|
|
15
|
+
* Instantiate an ImageSource
|
|
16
|
+
* @constructor
|
|
17
|
+
* @param {string} source - The source of the image data.
|
|
18
|
+
* @param {string} [type] - The type of data in the image source, valid values
|
|
19
|
+
* are 'url', 'base64', and 'dataurl'. If not provided 'base64' is the default.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const personPhoto = new ImageSource('/person/123.jpg', '123', 'url')
|
|
23
|
+
*/
|
|
24
|
+
constructor (source, type = 'base64') {
|
|
25
|
+
// TODO:
|
|
26
|
+
// If the source is typeof object and/or type=object we should do some duck
|
|
27
|
+
// typing and accept any of...
|
|
28
|
+
// - The result of an ICAO check that contains a cropped image
|
|
29
|
+
// - An Image tag (fetch the source)
|
|
30
|
+
// - A Blob
|
|
31
|
+
// - An Array Buffer
|
|
32
|
+
// - An object that has a fullCapture method (call function in .data())
|
|
33
|
+
this.type = type
|
|
34
|
+
switch (this.type) {
|
|
35
|
+
case 'url':
|
|
36
|
+
this.url = source
|
|
37
|
+
break
|
|
38
|
+
case 'base64':
|
|
39
|
+
this.imageData = source
|
|
40
|
+
break
|
|
41
|
+
case 'dataurl':
|
|
42
|
+
this.imageData = source.split(',')[1]
|
|
43
|
+
break
|
|
44
|
+
case undefined:
|
|
45
|
+
case null:
|
|
46
|
+
default:
|
|
47
|
+
throw new Error('Invalid image source type provided')
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Fetch the image data and base64 encode it
|
|
53
|
+
* @async
|
|
54
|
+
* @example
|
|
55
|
+
* const personPhoto = new ImageSource("/img/photo.jpg")
|
|
56
|
+
* await personPhoto.data()
|
|
57
|
+
* console.log(personPhoto.imageData)
|
|
58
|
+
*/
|
|
59
|
+
async data () {
|
|
60
|
+
if (!this.imageData && this.url) {
|
|
61
|
+
const response = await fetch(this.url)
|
|
62
|
+
await checkResponse(response)
|
|
63
|
+
const blob = await response.blob()
|
|
64
|
+
this.imageData = await blobToBase64(blob)
|
|
65
|
+
}
|
|
66
|
+
return this.imageData
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Create an <img> element, wait for it to load and return it
|
|
71
|
+
* @async
|
|
72
|
+
* @example
|
|
73
|
+
* // Load the image and draw it on a Canvas
|
|
74
|
+
* const img = await imgSrc.toImage()
|
|
75
|
+
* const canvas = document.createElement('canvas')
|
|
76
|
+
* const ctx = canvas.getContext('2d')
|
|
77
|
+
* canvas.width = img.width
|
|
78
|
+
* canvas.height = img.height
|
|
79
|
+
* ctx.drawImage(img, canvas.width, canvas.height, img.width, img.height)
|
|
80
|
+
*/
|
|
81
|
+
async toImage () {
|
|
82
|
+
const img = new window.Image()
|
|
83
|
+
const promise = new Promise((resolve, reject) => {
|
|
84
|
+
img.onload = (data) => resolve(img)
|
|
85
|
+
img.onerror = (err) => reject(err)
|
|
86
|
+
})
|
|
87
|
+
switch (this.type) {
|
|
88
|
+
case 'url':
|
|
89
|
+
img.src = this.url
|
|
90
|
+
break
|
|
91
|
+
case 'base64':
|
|
92
|
+
img.src = base64ToDataURL(this.imageData)
|
|
93
|
+
break
|
|
94
|
+
case 'dataurl':
|
|
95
|
+
img.src = this.source
|
|
96
|
+
break
|
|
97
|
+
case undefined:
|
|
98
|
+
case null:
|
|
99
|
+
default:
|
|
100
|
+
throw new Error('Invalid image source type provided')
|
|
101
|
+
}
|
|
102
|
+
return promise
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
toJSON () {
|
|
106
|
+
return this.imageData
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export default ImageSource
|
package/Version.js
CHANGED
package/examples/canon.html
CHANGED
|
@@ -15,52 +15,6 @@
|
|
|
15
15
|
Stream
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
|
18
|
-
<script type="module">
|
|
19
|
-
import CanonCamera from '/sdk/js/CanonCamera.js'
|
|
20
|
-
(async () => {
|
|
21
|
-
const defaultSrc = '/demo/img/empty.jpg'
|
|
22
|
-
const defaultWidth = 400
|
|
23
|
-
const img = document.getElementById('img')
|
|
24
|
-
const capture = document.getElementById('capture')
|
|
25
|
-
const stream = document.getElementById('stream')
|
|
26
|
-
const rotation = document.getElementById('rotate')
|
|
27
|
-
|
|
28
|
-
img.src = defaultSrc
|
|
29
|
-
img.width = defaultWidth
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const camera = new CanonCamera()
|
|
33
|
-
const devices = await camera.devices();
|
|
34
|
-
|
|
35
|
-
if (!devices.length) {
|
|
36
|
-
return alert('No Canon Camera devices found')
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Start the first device's live feed and stream it to the img tag
|
|
40
|
-
stream.addEventListener('click', async () => {
|
|
41
|
-
const rotate = parseInt(rotation.value)
|
|
42
|
-
rotation.disabled = true
|
|
43
|
-
stream.disabled = true
|
|
44
|
-
img.src = await camera.streamUrl({rotate})
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
// Take a full capture and add the image to the page
|
|
48
|
-
capture.addEventListener('click', async () => {
|
|
49
|
-
const rotate = parseInt(rotation.value)
|
|
50
|
-
const capture = document.createElement('img')
|
|
51
|
-
img.src = defaultSrc
|
|
52
|
-
capture.src = await camera.takePhoto({rotate})
|
|
53
|
-
capture.width = defaultWidth
|
|
54
|
-
document.body.appendChild(capture)
|
|
55
|
-
rotation.disabled = false
|
|
56
|
-
stream.disabled = false
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
} catch (e) {
|
|
60
|
-
console.error(e)
|
|
61
|
-
alert(`Error: ${e.message}`)
|
|
62
|
-
}
|
|
63
|
-
})()
|
|
64
|
-
</script>
|
|
18
|
+
<script type="module" src="./canon.js"></script>
|
|
65
19
|
</body>
|
|
66
20
|
</html>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import CanonCamera from '../../../../sdk/js/CanonCamera.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
const defaultSrc = 'empty.jpg'
|
|
4
|
+
const defaultWidth = 400
|
|
5
|
+
const img = document.getElementById('img')
|
|
6
|
+
const capture = document.getElementById('capture')
|
|
7
|
+
const stream = document.getElementById('stream')
|
|
8
|
+
const rotation = document.getElementById('rotate')
|
|
9
|
+
|
|
10
|
+
img.src = defaultSrc
|
|
11
|
+
img.width = defaultWidth
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const camera = new CanonCamera()
|
|
15
|
+
const devices = await camera.devices()
|
|
16
|
+
|
|
17
|
+
if (!devices.length) {
|
|
18
|
+
return window.alert('No Canon Camera devices found')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Start the first device's live feed and stream it to the img tag
|
|
22
|
+
stream.addEventListener('click', async () => {
|
|
23
|
+
const rotate = parseInt(rotation.value)
|
|
24
|
+
rotation.disabled = true
|
|
25
|
+
stream.disabled = true
|
|
26
|
+
img.src = await camera.streamUrl({ rotate })
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Take a full capture and add the image to the page
|
|
30
|
+
capture.addEventListener('click', async () => {
|
|
31
|
+
const rotate = parseInt(rotation.value)
|
|
32
|
+
const capture = document.createElement('img')
|
|
33
|
+
img.src = defaultSrc
|
|
34
|
+
capture.src = await camera.takePhoto({ rotate })
|
|
35
|
+
capture.width = defaultWidth
|
|
36
|
+
document.body.appendChild(capture)
|
|
37
|
+
rotation.disabled = false
|
|
38
|
+
stream.disabled = false
|
|
39
|
+
})
|
|
40
|
+
} catch (e) {
|
|
41
|
+
console.error(e)
|
|
42
|
+
window.alert(`Error: ${e.message}`)
|
|
43
|
+
}
|
|
44
|
+
})()
|
|
@@ -15,54 +15,6 @@
|
|
|
15
15
|
Stop Feed
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
|
18
|
-
<script type="module">
|
|
19
|
-
import CanonCamera from '/sdk/js/CanonCamera.js'
|
|
20
|
-
(async () => {
|
|
21
|
-
const defaultSrc = '/demo/img/empty.jpg'
|
|
22
|
-
const img = document.getElementById('img')
|
|
23
|
-
const rotation = document.getElementById('rotate')
|
|
24
|
-
const frame = document.getElementById('frame')
|
|
25
|
-
const stop = document.getElementById('stop')
|
|
26
|
-
|
|
27
|
-
img.src = defaultSrc
|
|
28
|
-
img.width = 400
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const camera = new CanonCamera()
|
|
32
|
-
const devices = await camera.devices()
|
|
33
|
-
|
|
34
|
-
if (!devices.length) {
|
|
35
|
-
return alert('No Canon Camera devices found')
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Acquiring the first frame will take a few seconds while the camera
|
|
39
|
-
// starts up and begins streaming, subsequent frames will be returned
|
|
40
|
-
// instantaneously
|
|
41
|
-
let lastFrame;
|
|
42
|
-
frame.addEventListener('click', async () => {
|
|
43
|
-
stop.disabled = true
|
|
44
|
-
rotation.disabled = true
|
|
45
|
-
const rotate = parseInt(rotation.value)
|
|
46
|
-
// Cleanup the last frame captured, if any
|
|
47
|
-
if (lastFrame) {
|
|
48
|
-
URL.revokeObjectURL(lastFrame)
|
|
49
|
-
}
|
|
50
|
-
img.src = lastFrame = await camera.getMostRecentFrame({rotate})
|
|
51
|
-
rotation.disabled = false
|
|
52
|
-
stop.disabled = false
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
// Stop live feed
|
|
56
|
-
stop.addEventListener('click', async () => {
|
|
57
|
-
const result = await camera.stopFeed()
|
|
58
|
-
alert(result.message || result.status)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
} catch (e) {
|
|
62
|
-
console.error(e)
|
|
63
|
-
alert(`Error: ${e.message}`)
|
|
64
|
-
}
|
|
65
|
-
})()
|
|
66
|
-
</script>
|
|
18
|
+
<script type="module" src="./canon_getframe.js"></script>
|
|
67
19
|
</body>
|
|
68
20
|
</html>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import CanonCamera from '../../../../sdk/js/CanonCamera.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
const defaultSrc = 'empty.jpg'
|
|
4
|
+
const img = document.getElementById('img')
|
|
5
|
+
const rotation = document.getElementById('rotate')
|
|
6
|
+
const frame = document.getElementById('frame')
|
|
7
|
+
const stop = document.getElementById('stop')
|
|
8
|
+
|
|
9
|
+
img.src = defaultSrc
|
|
10
|
+
img.width = 400
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const camera = new CanonCamera()
|
|
14
|
+
const devices = await camera.devices()
|
|
15
|
+
|
|
16
|
+
if (!devices.length) {
|
|
17
|
+
return window.alert('No Canon Camera devices found')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Acquiring the first frame will take a few seconds while the camera
|
|
21
|
+
// starts up and begins streaming, subsequent frames will be returned
|
|
22
|
+
// instantaneously
|
|
23
|
+
let lastFrame
|
|
24
|
+
frame.addEventListener('click', async () => {
|
|
25
|
+
stop.disabled = true
|
|
26
|
+
rotation.disabled = true
|
|
27
|
+
const rotate = parseInt(rotation.value)
|
|
28
|
+
// Cleanup the last frame captured, if any
|
|
29
|
+
if (lastFrame) {
|
|
30
|
+
URL.revokeObjectURL(lastFrame)
|
|
31
|
+
}
|
|
32
|
+
img.src = lastFrame = await camera.getMostRecentFrame({ rotate })
|
|
33
|
+
rotation.disabled = false
|
|
34
|
+
stop.disabled = false
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// Stop live feed
|
|
38
|
+
stop.addEventListener('click', async () => {
|
|
39
|
+
const result = await camera.stopFeed()
|
|
40
|
+
window.alert(result.message || result.status)
|
|
41
|
+
})
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.error(e)
|
|
44
|
+
window.alert(`Error: ${e.message}`)
|
|
45
|
+
}
|
|
46
|
+
})()
|
package/examples/canon_lan.html
CHANGED
|
@@ -15,54 +15,6 @@
|
|
|
15
15
|
Stream
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
|
18
|
-
<script type="module">
|
|
19
|
-
import CanonCamera from '/sdk/js/CanonCamera.js'
|
|
20
|
-
(async () => {
|
|
21
|
-
const defaultSrc = '/demo/img/empty.jpg'
|
|
22
|
-
const defaultWidth = 400
|
|
23
|
-
const img = document.getElementById('img')
|
|
24
|
-
const capture = document.getElementById('capture')
|
|
25
|
-
const stream = document.getElementById('stream')
|
|
26
|
-
const rotation = document.getElementById('rotate')
|
|
27
|
-
|
|
28
|
-
img.src = defaultSrc
|
|
29
|
-
img.width = defaultWidth
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const defaultURL = 'https://windev2-local.capturebridge.net:9001'
|
|
33
|
-
const url = prompt('Enter remote Base URL', defaultURL)
|
|
34
|
-
const camera = new CanonCamera(url)
|
|
35
|
-
const devices = await camera.devices();
|
|
36
|
-
|
|
37
|
-
if (!devices.length) {
|
|
38
|
-
return alert('No Canon Camera devices found')
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Start the first device's live feed and stream it to the img tag
|
|
42
|
-
stream.addEventListener('click', async () => {
|
|
43
|
-
const rotate = parseInt(rotation.value)
|
|
44
|
-
rotation.disabled = true
|
|
45
|
-
stream.disabled = true
|
|
46
|
-
img.src = await camera.streamUrl({rotate})
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
// Take a full capture and add the image to the page
|
|
50
|
-
capture.addEventListener('click', async () => {
|
|
51
|
-
const rotate = parseInt(rotation.value)
|
|
52
|
-
const capture = document.createElement('img')
|
|
53
|
-
img.src = defaultSrc
|
|
54
|
-
capture.src = await camera.takePhoto({rotate})
|
|
55
|
-
capture.width = defaultWidth
|
|
56
|
-
document.body.appendChild(capture)
|
|
57
|
-
rotation.disabled = false
|
|
58
|
-
stream.disabled = false
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
} catch (e) {
|
|
62
|
-
console.error(e)
|
|
63
|
-
alert(`Error: ${e.message}`)
|
|
64
|
-
}
|
|
65
|
-
})()
|
|
66
|
-
</script>
|
|
18
|
+
<script type="module" src="./canon_lan.js"></script>
|
|
67
19
|
</body>
|
|
68
20
|
</html>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import CanonCamera from '../../../../sdk/js/CanonCamera.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
const defaultSrc = 'empty.jpg'
|
|
4
|
+
const defaultWidth = 400
|
|
5
|
+
const img = document.getElementById('img')
|
|
6
|
+
const capture = document.getElementById('capture')
|
|
7
|
+
const stream = document.getElementById('stream')
|
|
8
|
+
const rotation = document.getElementById('rotate')
|
|
9
|
+
|
|
10
|
+
img.src = defaultSrc
|
|
11
|
+
img.width = defaultWidth
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const defaultURL = 'https://windev2-local.capturebridge.net:9001'
|
|
15
|
+
const url = window.prompt('Enter remote Base URL', defaultURL)
|
|
16
|
+
const camera = new CanonCamera(url)
|
|
17
|
+
const devices = await camera.devices()
|
|
18
|
+
|
|
19
|
+
if (!devices.length) {
|
|
20
|
+
return window.alert('No Canon Camera devices found')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Start the first device's live feed and stream it to the img tag
|
|
24
|
+
stream.addEventListener('click', async () => {
|
|
25
|
+
const rotate = parseInt(rotation.value)
|
|
26
|
+
rotation.disabled = true
|
|
27
|
+
stream.disabled = true
|
|
28
|
+
img.src = await camera.streamUrl({ rotate })
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
// Take a full capture and add the image to the page
|
|
32
|
+
capture.addEventListener('click', async () => {
|
|
33
|
+
const rotate = parseInt(rotation.value)
|
|
34
|
+
const capture = document.createElement('img')
|
|
35
|
+
img.src = defaultSrc
|
|
36
|
+
capture.src = await camera.takePhoto({ rotate })
|
|
37
|
+
capture.width = defaultWidth
|
|
38
|
+
document.body.appendChild(capture)
|
|
39
|
+
rotation.disabled = false
|
|
40
|
+
stream.disabled = false
|
|
41
|
+
})
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.error(e)
|
|
44
|
+
window.alert(`Error: ${e.message}`)
|
|
45
|
+
}
|
|
46
|
+
})()
|
|
@@ -2,36 +2,6 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head><title>Canon Camera Minimal Example</title></head>
|
|
4
4
|
<body>
|
|
5
|
-
<script type="module">
|
|
6
|
-
import CanonCamera from '/sdk/js/CanonCamera.js'
|
|
7
|
-
(async () => {
|
|
8
|
-
try {
|
|
9
|
-
|
|
10
|
-
// Instantiate a Canon Camera
|
|
11
|
-
const camera = new CanonCamera()
|
|
12
|
-
|
|
13
|
-
const devices = await camera.devices();
|
|
14
|
-
|
|
15
|
-
if (!devices.length) {
|
|
16
|
-
return alert('No Canon Camera devices found')
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Start the device's live feed and stream it to an img tag
|
|
20
|
-
const img = document.createElement('img')
|
|
21
|
-
img.src = await camera.streamUrl()
|
|
22
|
-
img.height = 400
|
|
23
|
-
document.body.appendChild(img)
|
|
24
|
-
|
|
25
|
-
// Demo live feed for a few seconds, take a picture, and update the img tag
|
|
26
|
-
setTimeout(async () => {
|
|
27
|
-
img.src = await camera.takePhoto()
|
|
28
|
-
}, 9000)
|
|
29
|
-
|
|
30
|
-
} catch (e) {
|
|
31
|
-
console.error(e)
|
|
32
|
-
alert(`Error: ${e.message}`)
|
|
33
|
-
}
|
|
34
|
-
})()
|
|
35
|
-
</script>
|
|
5
|
+
<script type="module" src="./canon_minimal.js"></script>
|
|
36
6
|
</body>
|
|
37
7
|
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import CanonCamera from '../../../../sdk/js/CanonCamera.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
try {
|
|
4
|
+
// Instantiate a Canon Camera
|
|
5
|
+
const camera = new CanonCamera()
|
|
6
|
+
|
|
7
|
+
const devices = await camera.devices()
|
|
8
|
+
|
|
9
|
+
if (!devices.length) {
|
|
10
|
+
return window.alert('No Canon Camera devices found')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Start the device's live feed and stream it to an img tag
|
|
14
|
+
const img = document.createElement('img')
|
|
15
|
+
img.src = await camera.streamUrl()
|
|
16
|
+
img.height = 400
|
|
17
|
+
document.body.appendChild(img)
|
|
18
|
+
|
|
19
|
+
// Demo live feed for a few seconds, take a picture, and update the img tag
|
|
20
|
+
setTimeout(async () => {
|
|
21
|
+
img.src = await camera.takePhoto()
|
|
22
|
+
}, 9000)
|
|
23
|
+
} catch (e) {
|
|
24
|
+
console.error(e)
|
|
25
|
+
window.alert(`Error: ${e.message}`)
|
|
26
|
+
}
|
|
27
|
+
})()
|
|
Binary file
|
|
Binary file
|
package/examples/icao.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import ICAO from '../../../../sdk/js/ICAO.js'
|
|
2
|
+
import ImageSource from '../../../../sdk/js/ImageSource.js'
|
|
3
|
+
|
|
4
|
+
(async () => {
|
|
5
|
+
try {
|
|
6
|
+
const icao = new ICAO()
|
|
7
|
+
const imgSrc = new ImageSource('icao.jpg', 'url')
|
|
8
|
+
|
|
9
|
+
// Perform an ICAO check against the provided Image and return cropped
|
|
10
|
+
const results = await icao.check(imgSrc, true)
|
|
11
|
+
|
|
12
|
+
// Our stock photo is zoomed in too close, so we pad the canvas to allow for
|
|
13
|
+
// drawing a box around the cropped portion
|
|
14
|
+
const padding = 150
|
|
15
|
+
|
|
16
|
+
// stroke/arc color
|
|
17
|
+
const color = 'rgba(0,255,0,0.5)'
|
|
18
|
+
|
|
19
|
+
// Load the image and draw it on a Canvas
|
|
20
|
+
const img = await imgSrc.toImage()
|
|
21
|
+
const canvas = document.createElement('canvas')
|
|
22
|
+
const ctx = canvas.getContext('2d')
|
|
23
|
+
canvas.width = img.width + padding
|
|
24
|
+
canvas.height = img.height + padding
|
|
25
|
+
ctx.drawImage(img, padding / 2, padding / 2, img.width, img.height)
|
|
26
|
+
|
|
27
|
+
document.body.appendChild(canvas)
|
|
28
|
+
|
|
29
|
+
ctx.strokeStyle = color
|
|
30
|
+
ctx.lineWidth = 4
|
|
31
|
+
|
|
32
|
+
// Insert cropped image into the DOM
|
|
33
|
+
const croppedSrc = new ImageSource(results.cropped)
|
|
34
|
+
document.body.appendChild(await croppedSrc.toImage())
|
|
35
|
+
|
|
36
|
+
// Draw points for left and right eye
|
|
37
|
+
ctx.beginPath()
|
|
38
|
+
ctx.arc(results.face.left_eye.x + padding / 2,
|
|
39
|
+
results.face.left_eye.y + padding / 2, 5, 0, 2 * Math.PI)
|
|
40
|
+
ctx.fillStyle = color
|
|
41
|
+
ctx.fill()
|
|
42
|
+
|
|
43
|
+
ctx.beginPath()
|
|
44
|
+
ctx.arc(results.face.right_eye.x + padding / 2,
|
|
45
|
+
results.face.right_eye.y + padding / 2, 5, 0, 2 * Math.PI)
|
|
46
|
+
ctx.fillStyle = color
|
|
47
|
+
ctx.fill()
|
|
48
|
+
|
|
49
|
+
// Draw bounding box where image was cropped
|
|
50
|
+
ctx.beginPath()
|
|
51
|
+
ctx.moveTo(results.crop_boundary[0].x + padding / 2,
|
|
52
|
+
results.crop_boundary[0].y + padding / 2)
|
|
53
|
+
for (let i = 1; i < results.crop_boundary.length; i++) {
|
|
54
|
+
ctx.lineTo(results.crop_boundary[i].x + padding / 2,
|
|
55
|
+
results.crop_boundary[i].y + padding / 2)
|
|
56
|
+
}
|
|
57
|
+
ctx.closePath()
|
|
58
|
+
ctx.stroke()
|
|
59
|
+
|
|
60
|
+
// Display ICAO attributes
|
|
61
|
+
const output = document.createElement('textarea')
|
|
62
|
+
output.style.display = 'block'
|
|
63
|
+
output.rows = 35
|
|
64
|
+
output.cols = 50
|
|
65
|
+
output.value = '# Checks\n\n'
|
|
66
|
+
document.body.appendChild(output)
|
|
67
|
+
results.attributes.filter(attr => attr.type === 'check').forEach(({ id, score, compliant }) => {
|
|
68
|
+
output.value += (compliant ? '✅' : '❌') + `${id}: ${score}\n`
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
output.value += '\n\n# Data\n\n'
|
|
72
|
+
|
|
73
|
+
results.attributes.filter(attr => attr.type === 'data').forEach(({ id, score, data }) => {
|
|
74
|
+
output.value += `${id}: ${data || score}\n`
|
|
75
|
+
})
|
|
76
|
+
} catch (e) {
|
|
77
|
+
console.error(e)
|
|
78
|
+
window.alert(`Error: ${e.message}`)
|
|
79
|
+
}
|
|
80
|
+
})()
|
package/examples/mockcamera.html
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head><title>Mock Camera Example</title></head>
|
|
4
4
|
<body>
|
|
5
|
-
<img id="img" src="
|
|
5
|
+
<img id="img" src="empty.jpg"/>
|
|
6
6
|
<div>
|
|
7
7
|
<div>
|
|
8
8
|
<label>Rotate</label>
|
|
@@ -15,47 +15,6 @@
|
|
|
15
15
|
Stream
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
|
18
|
-
<script type="module">
|
|
19
|
-
import MockCamera from '/sdk/js/MockCamera.js'
|
|
20
|
-
(async () => {
|
|
21
|
-
const defaultSrc = '/demo/img/empty.jpg'
|
|
22
|
-
const defaultWidth = 400
|
|
23
|
-
const img = document.getElementById('img')
|
|
24
|
-
const capture = document.getElementById('capture')
|
|
25
|
-
const stream = document.getElementById('stream')
|
|
26
|
-
const rotation = document.getElementById('rotate')
|
|
27
|
-
|
|
28
|
-
img.src = defaultSrc
|
|
29
|
-
img.width = defaultWidth
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const camera = new MockCamera()
|
|
33
|
-
|
|
34
|
-
// Start the first device's live feed and stream it to the img tag
|
|
35
|
-
stream.addEventListener('click', async () => {
|
|
36
|
-
const rotate = parseInt(rotation.value)
|
|
37
|
-
rotation.disabled = true
|
|
38
|
-
stream.disabled = true
|
|
39
|
-
img.src = await camera.streamUrl({rotate})
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// Take a full capture and add the image to the page
|
|
43
|
-
capture.addEventListener('click', async () => {
|
|
44
|
-
const rotate = parseInt(rotation.value)
|
|
45
|
-
const capture = document.createElement('img')
|
|
46
|
-
img.src = defaultSrc
|
|
47
|
-
capture.src = await camera.takePhoto({rotate})
|
|
48
|
-
capture.width = defaultWidth
|
|
49
|
-
document.body.appendChild(capture)
|
|
50
|
-
rotation.disabled = false
|
|
51
|
-
stream.disabled = false
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
} catch (e) {
|
|
55
|
-
console.error(e)
|
|
56
|
-
alert(`Error: ${e.message}`)
|
|
57
|
-
}
|
|
58
|
-
})()
|
|
59
|
-
</script>
|
|
18
|
+
<script type="module" src="./mockcamera.js"></script>
|
|
60
19
|
</body>
|
|
61
20
|
</html>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import MockCamera from '../../../../sdk/js/MockCamera.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
const defaultSrc = 'empty.jpg'
|
|
4
|
+
const defaultWidth = 400
|
|
5
|
+
const img = document.getElementById('img')
|
|
6
|
+
const capture = document.getElementById('capture')
|
|
7
|
+
const stream = document.getElementById('stream')
|
|
8
|
+
const rotation = document.getElementById('rotate')
|
|
9
|
+
|
|
10
|
+
img.src = defaultSrc
|
|
11
|
+
img.width = defaultWidth
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const camera = new MockCamera()
|
|
15
|
+
|
|
16
|
+
// Start the first device's live feed and stream it to the img tag
|
|
17
|
+
stream.addEventListener('click', async () => {
|
|
18
|
+
const rotate = parseInt(rotation.value)
|
|
19
|
+
rotation.disabled = true
|
|
20
|
+
stream.disabled = true
|
|
21
|
+
img.src = await camera.streamUrl({ rotate })
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Take a full capture and add the image to the page
|
|
25
|
+
capture.addEventListener('click', async () => {
|
|
26
|
+
const rotate = parseInt(rotation.value)
|
|
27
|
+
const capture = document.createElement('img')
|
|
28
|
+
img.src = defaultSrc
|
|
29
|
+
capture.src = await camera.takePhoto({ rotate })
|
|
30
|
+
capture.width = defaultWidth
|
|
31
|
+
document.body.appendChild(capture)
|
|
32
|
+
rotation.disabled = false
|
|
33
|
+
stream.disabled = false
|
|
34
|
+
})
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.error(e)
|
|
37
|
+
window.alert(`Error: ${e.message}`)
|
|
38
|
+
}
|
|
39
|
+
})()
|
|
@@ -15,49 +15,6 @@
|
|
|
15
15
|
Stop Feed
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
|
18
|
-
<script type="module">
|
|
19
|
-
import MockCamera from '/sdk/js/MockCamera.js'
|
|
20
|
-
(async () => {
|
|
21
|
-
const defaultSrc = '/demo/img/empty.jpg'
|
|
22
|
-
const img = document.getElementById('img')
|
|
23
|
-
const rotation = document.getElementById('rotate')
|
|
24
|
-
const frame = document.getElementById('frame')
|
|
25
|
-
const stop = document.getElementById('stop')
|
|
26
|
-
|
|
27
|
-
img.src = defaultSrc
|
|
28
|
-
img.width = 400
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const camera = new MockCamera()
|
|
32
|
-
const devices = await camera.devices()
|
|
33
|
-
|
|
34
|
-
// Grab a frame from the live feed
|
|
35
|
-
let lastFrame;
|
|
36
|
-
frame.addEventListener('click', async () => {
|
|
37
|
-
stop.disabled = true
|
|
38
|
-
rotation.disabled = true
|
|
39
|
-
const rotate = parseInt(rotation.value)
|
|
40
|
-
// Cleanup the last frame captured, if any
|
|
41
|
-
if (lastFrame) {
|
|
42
|
-
URL.revokeObjectURL(lastFrame)
|
|
43
|
-
}
|
|
44
|
-
img.src = lastFrame = await camera.getMostRecentFrame({rotate})
|
|
45
|
-
document.body.appendChild(frame)
|
|
46
|
-
rotation.disabled = false
|
|
47
|
-
stop.disabled = false
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
// Stop live feed
|
|
51
|
-
stop.addEventListener('click', async () => {
|
|
52
|
-
const result = await camera.stopFeed()
|
|
53
|
-
alert(result.message || result.status)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
} catch (e) {
|
|
57
|
-
console.error(e)
|
|
58
|
-
alert(`Error: ${e.message}`)
|
|
59
|
-
}
|
|
60
|
-
})()
|
|
61
|
-
</script>
|
|
18
|
+
<script type="module" src="./mockcamera_getframe.js"></script>
|
|
62
19
|
</body>
|
|
63
20
|
</html>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import MockCamera from '../../../../sdk/js/MockCamera.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
const defaultSrc = 'empty.jpg'
|
|
4
|
+
const img = document.getElementById('img')
|
|
5
|
+
const rotation = document.getElementById('rotate')
|
|
6
|
+
const frame = document.getElementById('frame')
|
|
7
|
+
const stop = document.getElementById('stop')
|
|
8
|
+
|
|
9
|
+
img.src = defaultSrc
|
|
10
|
+
img.width = 400
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const camera = new MockCamera()
|
|
14
|
+
|
|
15
|
+
// Grab a frame from the live feed
|
|
16
|
+
let lastFrame
|
|
17
|
+
frame.addEventListener('click', async () => {
|
|
18
|
+
stop.disabled = true
|
|
19
|
+
rotation.disabled = true
|
|
20
|
+
const rotate = parseInt(rotation.value)
|
|
21
|
+
// Cleanup the last frame captured, if any
|
|
22
|
+
if (lastFrame) {
|
|
23
|
+
URL.revokeObjectURL(lastFrame)
|
|
24
|
+
}
|
|
25
|
+
img.src = lastFrame = await camera.getMostRecentFrame({ rotate })
|
|
26
|
+
document.body.appendChild(frame)
|
|
27
|
+
rotation.disabled = false
|
|
28
|
+
stop.disabled = false
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
// Stop live feed
|
|
32
|
+
stop.addEventListener('click', async () => {
|
|
33
|
+
const result = await camera.stopFeed()
|
|
34
|
+
window.alert(result.message || result.status)
|
|
35
|
+
})
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.error(e)
|
|
38
|
+
window.alert(`Error: ${e.message}`)
|
|
39
|
+
}
|
|
40
|
+
})()
|
|
@@ -2,30 +2,6 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head><title>Mock Camera Minimal Example</title></head>
|
|
4
4
|
<body>
|
|
5
|
-
<script type="module">
|
|
6
|
-
import MockCamera from '/sdk/js/MockCamera.js'
|
|
7
|
-
(async () => {
|
|
8
|
-
try {
|
|
9
|
-
|
|
10
|
-
// Instantiate a Mock Camera
|
|
11
|
-
const camera = new MockCamera()
|
|
12
|
-
|
|
13
|
-
// Start the device's live feed and stream it to an img tag
|
|
14
|
-
const img = document.createElement('img')
|
|
15
|
-
img.src = await camera.streamUrl()
|
|
16
|
-
img.height = 400
|
|
17
|
-
document.body.appendChild(img)
|
|
18
|
-
|
|
19
|
-
// Demo live feed for a few seconds, take a picture, and update the img tag
|
|
20
|
-
setTimeout(async () => {
|
|
21
|
-
img.src = await camera.takePhoto()
|
|
22
|
-
}, 9000)
|
|
23
|
-
|
|
24
|
-
} catch (e) {
|
|
25
|
-
console.error(e)
|
|
26
|
-
alert(`Error: ${e.message}`)
|
|
27
|
-
}
|
|
28
|
-
})()
|
|
29
|
-
</script>
|
|
5
|
+
<script type="module" src="./mockcamera_minimal.js"></script>
|
|
30
6
|
</body>
|
|
31
7
|
</html>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import MockCamera from '../../../../sdk/js/MockCamera.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
try {
|
|
4
|
+
// Instantiate a Mock Camera
|
|
5
|
+
const camera = new MockCamera()
|
|
6
|
+
|
|
7
|
+
// Start the device's live feed and stream it to an img tag
|
|
8
|
+
const img = document.createElement('img')
|
|
9
|
+
img.src = await camera.streamUrl()
|
|
10
|
+
img.height = 400
|
|
11
|
+
document.body.appendChild(img)
|
|
12
|
+
|
|
13
|
+
// Demo live feed for a few seconds, take a picture, and update the img tag
|
|
14
|
+
setTimeout(async () => {
|
|
15
|
+
img.src = await camera.takePhoto()
|
|
16
|
+
}, 9000)
|
|
17
|
+
} catch (e) {
|
|
18
|
+
console.error(e)
|
|
19
|
+
window.alert(`Error: ${e.message}`)
|
|
20
|
+
}
|
|
21
|
+
})()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Verifone from '../../../../sdk/js/Verifone.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
try {
|
|
4
|
+
const tablet = new Verifone()
|
|
5
|
+
|
|
6
|
+
const img = document.createElement('img')
|
|
7
|
+
img.src = await tablet.signature({ format: 'jpg' })
|
|
8
|
+
await tablet.clear()
|
|
9
|
+
document.body.appendChild(img)
|
|
10
|
+
} catch (e) {
|
|
11
|
+
console.error(e)
|
|
12
|
+
window.alert(`Error: ${e.message}`)
|
|
13
|
+
}
|
|
14
|
+
})()
|
|
@@ -3,30 +3,6 @@
|
|
|
3
3
|
<head><title>Windows Scanner Example</title></head>
|
|
4
4
|
<body>
|
|
5
5
|
<img id="img"/>
|
|
6
|
-
<script type="module">
|
|
7
|
-
import WindowsScanner from '/sdk/js/WindowsScanner.js'
|
|
8
|
-
(async () => {
|
|
9
|
-
try {
|
|
10
|
-
|
|
11
|
-
const scanner = new WindowsScanner()
|
|
12
|
-
|
|
13
|
-
const devices = await scanner.devices();
|
|
14
|
-
|
|
15
|
-
if (!devices.length) {
|
|
16
|
-
return alert('No Scanner devices found')
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let scan = await scanner.scan()
|
|
20
|
-
|
|
21
|
-
document.createElement('img')
|
|
22
|
-
img.src = await scanner.scan()
|
|
23
|
-
document.body.appendChild(img)
|
|
24
|
-
|
|
25
|
-
} catch (e) {
|
|
26
|
-
console.error(e)
|
|
27
|
-
alert(`Error: ${e.message}`)
|
|
28
|
-
}
|
|
29
|
-
})()
|
|
30
|
-
</script>
|
|
6
|
+
<script type="module" src="./windows_scanner_minimal.js"></script>
|
|
31
7
|
</body>
|
|
32
8
|
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import WindowsScanner from '../../../../sdk/js/WindowsScanner.js'
|
|
2
|
+
(async () => {
|
|
3
|
+
try {
|
|
4
|
+
const scanner = new WindowsScanner()
|
|
5
|
+
|
|
6
|
+
const devices = await scanner.devices()
|
|
7
|
+
|
|
8
|
+
if (!devices.length) {
|
|
9
|
+
return window.alert('No Scanner devices found')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const img = document.createElement('img')
|
|
13
|
+
img.src = await scanner.scan()
|
|
14
|
+
document.body.appendChild(img)
|
|
15
|
+
} catch (e) {
|
|
16
|
+
console.error(e)
|
|
17
|
+
window.alert(`Error: ${e.message}`)
|
|
18
|
+
}
|
|
19
|
+
})()
|
package/package.json
CHANGED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head><title>Verifone Minimal Example</title></head>
|
|
4
|
-
<body>
|
|
5
|
-
<script type="module">
|
|
6
|
-
import Verifone from '/sdk/js/Verifone.js'
|
|
7
|
-
(async () => {
|
|
8
|
-
try {
|
|
9
|
-
const tablet = new Verifone()
|
|
10
|
-
|
|
11
|
-
const img = document.createElement('img')
|
|
12
|
-
img.src = await tablet.signature({format: 'jpg'})
|
|
13
|
-
await tablet.clear()
|
|
14
|
-
document.body.appendChild(img)
|
|
15
|
-
|
|
16
|
-
} catch (e) {
|
|
17
|
-
console.error(e)
|
|
18
|
-
alert(`Error: ${e.message}`)
|
|
19
|
-
}
|
|
20
|
-
})()
|
|
21
|
-
</script>
|
|
22
|
-
</body>
|
|
23
|
-
</html>
|