project done before
This commit is contained in:
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Generated by package manager
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Generated by Cordova
|
||||||
|
/plugins/
|
||||||
|
/platforms/
|
||||||
1
.vscode/plugins.json
vendored
Normal file
1
.vscode/plugins.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"plugins":["cordova-plugin-android-permissions","cordova-plugin-permission","cordova-plugin-whitelist"]}
|
||||||
80
.vscode/typings/cordova/cordova.d.ts
vendored
Normal file
80
.vscode/typings/cordova/cordova.d.ts
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Type definitions for Apache Cordova
|
||||||
|
// Project: http://cordova.apache.org
|
||||||
|
// Definitions by: Microsoft Open Technologies Inc. <http://msopentech.com>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
interface Cordova {
|
||||||
|
/** Invokes native functionality by specifying corresponding service name, action and optional parameters.
|
||||||
|
* @param success A success callback function.
|
||||||
|
* @param fail An error callback function.
|
||||||
|
* @param service The service name to call on the native side (corresponds to a native class).
|
||||||
|
* @param action The action name to call on the native side (generally corresponds to the native class method).
|
||||||
|
* @param args An array of arguments to pass into the native environment.
|
||||||
|
*/
|
||||||
|
exec(success: () => any, fail: () => any, service: string, action: string, args?: string[]): void;
|
||||||
|
/** Gets the operating system name. */
|
||||||
|
platformId: string;
|
||||||
|
/** Gets Cordova framework version */
|
||||||
|
version: string;
|
||||||
|
/** Defines custom logic as a Cordova module. Other modules can later access it using module name provided. */
|
||||||
|
define(moduleName: string, factory: (require: any, exports: any, module: any) => any): void;
|
||||||
|
/** Access a Cordova module by name. */
|
||||||
|
require(moduleName: string): any;
|
||||||
|
/** Namespace for Cordova plugin functionality */
|
||||||
|
plugins:CordovaPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CordovaPlugins {}
|
||||||
|
|
||||||
|
interface Document {
|
||||||
|
addEventListener(type: "deviceready", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "resume", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "backbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "menubutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "searchbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "startcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "endcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "volumedownbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
addEventListener(type: "volumeupbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
|
||||||
|
removeEventListener(type: "deviceready", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "resume", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "backbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "menubutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "searchbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "startcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "endcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "volumedownbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: "volumeupbutton", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
|
||||||
|
addEventListener(type: string, listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
removeEventListener(type: string, listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Window {
|
||||||
|
cordova:Cordova;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cordova/argscheck module
|
||||||
|
interface ArgsCheck {
|
||||||
|
checkArgs(argsSpec: string, functionName: string, args: any[], callee?: any): void;
|
||||||
|
getValue(value?: any, defaultValue?: any): any;
|
||||||
|
enableChecks: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cordova/urlutil module
|
||||||
|
interface UrlUtil {
|
||||||
|
makeAbsolute(url: string): string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Apache Cordova instance */
|
||||||
|
declare var cordova: Cordova;
|
||||||
|
|
||||||
|
declare module 'cordova' {
|
||||||
|
export = cordova;
|
||||||
|
}
|
||||||
25
config.xml
Normal file
25
config.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<widget id="com.barcode_barang.app" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||||
|
<name>Barcode_barang</name>
|
||||||
|
<description>
|
||||||
|
A sample Apache Cordova application that responds to the deviceready event.
|
||||||
|
</description>
|
||||||
|
<author email="dev@cordova.apache.org" href="http://cordova.io">
|
||||||
|
Apache Cordova Team
|
||||||
|
</author>
|
||||||
|
<content src="index.html" />
|
||||||
|
<access origin="*" subdomains="true"/>
|
||||||
|
<allow-intent href="http://*/*" />
|
||||||
|
<allow-intent href="https://*/*" />
|
||||||
|
<allow-intent href="tel:*" />
|
||||||
|
<allow-intent href="sms:*" />
|
||||||
|
<allow-intent href="mailto:*" />
|
||||||
|
<allow-intent href="geo:*" />
|
||||||
|
<platform name="android">
|
||||||
|
<allow-intent href="market:*" />
|
||||||
|
</platform>
|
||||||
|
<platform name="ios">
|
||||||
|
<allow-intent href="itms:*" />
|
||||||
|
<allow-intent href="itms-apps:*" />
|
||||||
|
</platform>
|
||||||
|
</widget>
|
||||||
1
jsconfig.json
Normal file
1
jsconfig.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1423
package-lock.json
generated
Normal file
1423
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
33
package.json
Normal file
33
package.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "com.barcode_barang.app",
|
||||||
|
"displayName": "Barcode_barang",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A sample Apache Cordova application that responds to the deviceready event.",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"ecosystem:cordova"
|
||||||
|
],
|
||||||
|
"author": "Apache Cordova Team",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"cordova-android": "^9.0.0",
|
||||||
|
"cordova-browser": "^6.0.0",
|
||||||
|
"cordova-plugin-android-permissions": "^1.1.2",
|
||||||
|
"cordova-plugin-permission": "^0.1.0",
|
||||||
|
"cordova-plugin-whitelist": "^1.3.4"
|
||||||
|
},
|
||||||
|
"cordova": {
|
||||||
|
"plugins": {
|
||||||
|
"cordova-plugin-whitelist": {},
|
||||||
|
"cordova-plugin-android-permissions": {},
|
||||||
|
"cordova-plugin-permission": {}
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
"android",
|
||||||
|
"browser"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
15
readme.rst
Normal file
15
readme.rst
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
###################
|
||||||
|
Barcode Barang User
|
||||||
|
###################
|
||||||
|
|
||||||
|
Aplikasi Mobile Scan Barcode Pada Barangan Toko Menggunakan Cordova
|
||||||
|
|
||||||
|
*******************
|
||||||
|
Contact
|
||||||
|
*******************
|
||||||
|
|
||||||
|
- Facebook https://www.facebook.com/kicap.karan>
|
||||||
|
- Portfolio Website https://www.kicap-karan.com/
|
||||||
|
- Linkedin https://www.linkedin.com/in/kicap-karan-85588b203/
|
||||||
|
- Whatsapp +6282293246583
|
||||||
|
|
||||||
2
typings/cordova-typings.d.ts
vendored
Normal file
2
typings/cordova-typings.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
/// <reference path="..\.vscode\typings\cordova\cordova.d.ts"/>
|
||||||
83
www/camera_example.html
Normal file
83
www/camera_example.html
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
|
|
||||||
|
<title>Camera</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
||||||
|
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
|
||||||
|
|
||||||
|
function getUserMedia(constraints, success, failure) {
|
||||||
|
navigator.getUserMedia(constraints, function(stream) {
|
||||||
|
var videoSrc = (window.URL && window.URL.createObjectURL(stream)) || stream;
|
||||||
|
success.apply(null, [videoSrc]);
|
||||||
|
}, failure);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function initCamera(constraints, video, callback) {
|
||||||
|
getUserMedia(constraints, function (src) {
|
||||||
|
video.src = src;
|
||||||
|
video.addEventListener('loadeddata', function() {
|
||||||
|
var attempts = 10;
|
||||||
|
|
||||||
|
function checkVideo() {
|
||||||
|
if (attempts > 0) {
|
||||||
|
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
||||||
|
console.log(video.videoWidth + "px x " + video.videoHeight + "px");
|
||||||
|
video.play();
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
window.setTimeout(checkVideo, 100);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback('Unable to play video stream.');
|
||||||
|
}
|
||||||
|
attempts--;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkVideo();
|
||||||
|
}, false);
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToCanvas(video, ctx) {
|
||||||
|
( function frame() {
|
||||||
|
ctx.drawImage(video, 0, 0);
|
||||||
|
window.requestAnimationFrame(frame);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
var constraints = {
|
||||||
|
video: {
|
||||||
|
mandatory: {
|
||||||
|
minWidth: 1280,
|
||||||
|
minHeight: 720
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
video = document.createElement('video'),
|
||||||
|
canvas = document.createElement('canvas');
|
||||||
|
|
||||||
|
document.body.appendChild(video);
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
|
||||||
|
initCamera(constraints, video, function() {
|
||||||
|
canvas.setAttribute('width', video.videoWidth);
|
||||||
|
canvas.setAttribute('height', video.videoHeight);
|
||||||
|
copyToCanvas(video, canvas.getContext('2d'));
|
||||||
|
});
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
27
www/config.rb
Normal file
27
www/config.rb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
# Require any additional compass plugins here.
|
||||||
|
|
||||||
|
|
||||||
|
# Set this to the root of your project when deployed:
|
||||||
|
http_path = "/"
|
||||||
|
css_dir = "css"
|
||||||
|
sass_dir = "sass"
|
||||||
|
images_dir = "img"
|
||||||
|
javascripts_dir = "js"
|
||||||
|
fonts_dir="fonts"
|
||||||
|
|
||||||
|
# You can select your preferred output style here (can be overridden via the command line):
|
||||||
|
# output_style = :expanded or :nested or :compact or :compressed
|
||||||
|
|
||||||
|
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||||
|
# relative_assets = true
|
||||||
|
|
||||||
|
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
||||||
|
# line_comments = false
|
||||||
|
|
||||||
|
|
||||||
|
# If you prefer the indented syntax, you might want to regenerate this
|
||||||
|
# project again passing --syntax sass, or you can uncomment this:
|
||||||
|
# preferred_syntax = :sass
|
||||||
|
# and then run:
|
||||||
|
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
||||||
16
www/css/colors.css
Normal file
16
www/css/colors.css
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
/* LESS - http://lesscss.org style sheet */
|
||||||
|
/* Palette color codes */
|
||||||
|
/* Palette URL: http://paletton.com/#uid=31g0q0kHZAviRSkrHLOGomVNzac */
|
||||||
|
/* Feel free to copy&paste color codes to your application */
|
||||||
|
/* MIXINS */
|
||||||
|
/* As hex codes */
|
||||||
|
/* Main Primary color */
|
||||||
|
/* Main Secondary color (1) */
|
||||||
|
/* Main Secondary color (2) */
|
||||||
|
/* As RGBa codes */
|
||||||
|
/* Main Primary color */
|
||||||
|
/* Main Secondary color (1) */
|
||||||
|
/* Main Secondary color (2) */
|
||||||
|
/* Generated by Paletton.com ├é┬® 2002-2014 */
|
||||||
|
/* http://paletton.com */
|
||||||
1
www/css/fonts.css
Normal file
1
www/css/fonts.css
Normal file
@ -0,0 +1 @@
|
|||||||
|
@import url("https://fonts.googleapis.com/css?family=Ubuntu:400,700|Cabin+Condensed:400,600");
|
||||||
298
www/css/styles.css
Normal file
298
www/css/styles.css
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
@import url("https://fonts.googleapis.com/css?family=Ubuntu:400,700|Cabin+Condensed:400,600");
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #FFF;
|
||||||
|
margin: 0px;
|
||||||
|
font-family: Ubuntu, sans-serif;
|
||||||
|
color: #1e1e1e;
|
||||||
|
font-weight: normal;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4 {
|
||||||
|
font-family: "Cabin Condensed", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background: #FFC600;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .headline {
|
||||||
|
max-width: 640px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .headline h1 {
|
||||||
|
color: #FFDD69;
|
||||||
|
font-size: 3em;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .headline h2 {
|
||||||
|
margin-top: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
background: #0A4DB7;
|
||||||
|
color: #6C9CE8;
|
||||||
|
padding: 1em 2em 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
width: 640px;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interactive.viewport {
|
||||||
|
width: 640px;
|
||||||
|
height: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#interactive.viewport canvas, video {
|
||||||
|
float: left;
|
||||||
|
width: 640px;
|
||||||
|
height: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interactive.viewport canvas.drawingBuffer, video.drawingBuffer {
|
||||||
|
margin-left: -640px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls fieldset {
|
||||||
|
border: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls .input-group {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls .input-group input, .controls .input-group button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls .reader-config-group {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls .reader-config-group label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls .reader-config-group label span {
|
||||||
|
width: 9rem;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#result_strip {
|
||||||
|
margin: 10px 0;
|
||||||
|
border-top: 1px solid #EEE;
|
||||||
|
border-bottom: 1px solid #EEE;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip > ul {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
width: auto;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip > ul > li {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip > ul > li .thumbnail {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 4px;
|
||||||
|
border: 1px dashed #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip > ul > li .thumbnail img {
|
||||||
|
max-width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip > ul > li .thumbnail .caption {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip > ul > li .thumbnail .caption h4 {
|
||||||
|
text-align: center;
|
||||||
|
word-wrap: break-word;
|
||||||
|
height: 40px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip > ul:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.scanner-overlay {
|
||||||
|
display: none;
|
||||||
|
width: 640px;
|
||||||
|
height: 510px;
|
||||||
|
position: absolute;
|
||||||
|
padding: 20px;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -275px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -340px;
|
||||||
|
background-color: #FFF;
|
||||||
|
-moz-box-shadow: #333333 0px 4px 10px;
|
||||||
|
-webkit-box-shadow: #333333 0px 4px 10px;
|
||||||
|
box-shadow: #333333 0px 4px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scanner-overlay > .header {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scanner-overlay > .header h4, .scanner-overlay > .header .close {
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scanner-overlay > .header h4 {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scanner-overlay > .header .close {
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
top: 0px;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
i.icon-24-scan {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzFFMjMzNTBFNjcwMTFFMkIzMERGOUMzMzEzM0E1QUMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzFFMjMzNTFFNjcwMTFFMkIzMERGOUMzMzEzM0E1QUMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMUUyMzM0RUU2NzAxMUUyQjMwREY5QzMzMTMzQTVBQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMUUyMzM0RkU2NzAxMUUyQjMwREY5QzMzMTMzQTVBQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtQr90wAAAUuSURBVHjanFVLbFRVGP7ua97T9DGPthbamAYYBNSMVbBpjCliWWGIEBMWsnDJxkh8RDeEDW5MDGticMmGBWnSlRSCwgLFNkqmmrRIqzjTznTazkxn5s7c6/efzm0G0Jhwkj/nP+d/nv91tIWFBTQaDQWapkGW67p4ltUub5qmAi0UCqF/a/U2m81tpmddotwwDGSz2dzi4uKSaOucnJycGhsbe1XXdQiIIcdxEAgEtgXq9brySHCht79UXi/8QheawN27d385fPjwuEl6XyKR6LdtW7t06RLK5TKOHj2K/fv3Q87Dw8OYn5/HiRMnMDs7i5mZGQwODiqlPp8PuVwO6XRaOXb16lXl1OnTp5FMJvtosF8M+MWLarWqGJaWlpBKpRRcu3YN4+PjmJ6exsTEhDJw5coVjI6OKgPhcBiZTAbxeBx+vx+XL19Gd3c3Tp48Ka9zqDYgBlTQxYNgMIhIJKLCILkQb+TZsgvdsiyFi+feWRR7oRNZyanQtvW2V4DEUUBiK2eJpeDirSyhCe7F2QPh8fiEp72i9PbsC5G52DbiKZA771yr1dTuGfJ4PQNPFoAyQNR1aNEmsS5eyB3PgjeooMZd2AWvNmzYci/Gea7TeFOcI93jV/K67noGmi4vdRI9gPSDeMLSdKUBZZczlWm1rTtHjLZ24d+WER2tc8N1m+Y+ID74wx0zGYvhg9UNrJdtHJyZRdQfwPsrq9g99xsGlgsYmr6BNzO/IVwsYfjBQ6XYz6JI/72MV366B5/lw0elOkJWGUM3bmKtWjXSLuLaBWhnPnnp0FfoiFi4+TMfVAb2poBkDLjO845uYLEAjL4ALGWBP5YAOsP4AJYBFDaB1HOSVWD2PuV95H2RdV93Lv74/cf6p6Zxq/h6OofeOPJBC39JtONdwOAAViOs4p4OFGTf0Uc8iiyrr9YdQrUnDLsngrVOC0jQib44HlF2RafRZBz1Qy+vfhgK3NJZBlrm+LEm9qWwzFgLU7Ozg0JxZP06jQSRpQ7EerAWDSt6PuhHPmChEAog56fCLvJT5hHTm3OZkz3DyLx7XNWTGEA1GkV14gjWgwbW0ESVjYRwCOuai03L5E7OUBAV4kXSS4auoGIaKOma4m8EA5R1sMEGLh95C+XuLph0WJWpxepYYLtfT0RRgY1KgNODY6BoaChRuEhDCIZQYseuki5KN6hcQHiq7OZNv4/Zq2O6P4Lfkwn46vZjjaYZrIpvWbpzjLErrc4xUGE4avRedpYJalRcIl5hQius/SrPm9xrNOQYJhao6BvNUeWqtY8KaWuNjHOFAr7mM9f4NA4UbKysoUJ8PV9UzVOx6wxDDWUOxnK1pmCD07fOMAvtIsM3l89Dl3HRGhVma9AZMqjOnz2LQqWCxs6dqr3T7x1DTzKJaG8SekcHhg4cgI/56uKdlKnBV/WndqN3YAB/7tyBd3oT6GBIOzs7kc/nDfFdDFT5bS73cp06dQoaPa/Rw/rtO/resTHxxE2m9rCrbSR27UJCcMf1BpiA5rAAGgdfc868fUR1sMwj0cm9Iu9IctweisViB3hhKTHDcHc5jv/LspbyaZrR1OD82/fIlOkuB9LnEWRmDX2TsddUPg3D5gvuc0je0rZaD5EW6G3yjS+A3eeBEWq3XW/Abw1HhUspXADufQb86oW7tZytkYCN//3hHwBvDALPi8EnSOYK8DAOfCc2h4aGcO7cuafkzampqf9UripH12/DtOZbx8ciVGzYy5OO40o25ascGRl5Ssc/AgwAjW3JwqIUjSYAAAAASUVORK5CYII=");
|
||||||
|
display: inline-block;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
line-height: 24px;
|
||||||
|
margin-top: 1px;
|
||||||
|
vertical-align: text-top;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 603px) {
|
||||||
|
|
||||||
|
#container {
|
||||||
|
width: 300px;
|
||||||
|
margin: 10px auto;
|
||||||
|
-moz-box-shadow: none;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#container form.voucher-form input.voucher-code {
|
||||||
|
width: 180px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 603px) {
|
||||||
|
|
||||||
|
.reader-config-group {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reader-config-group label > span {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reader-config-group label > select, .reader-config-group label > input {
|
||||||
|
max-width: calc(50% - 2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#interactive.viewport {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#interactive.viewport canvas, video {
|
||||||
|
margin-top: -50px;
|
||||||
|
width: 300px;
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interactive.viewport canvas.drawingBuffer, video.drawingBuffer {
|
||||||
|
margin-left: -300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#result_strip {
|
||||||
|
margin-top: 5px;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip ul.thumbnails > li {
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip ul.thumbnails > li .thumbnail .imgWrapper {
|
||||||
|
width: 130px;
|
||||||
|
height: 130px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result_strip ul.thumbnails > li .thumbnail .imgWrapper img {
|
||||||
|
margin-top: -25px;
|
||||||
|
width: 130px;
|
||||||
|
height: 180px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 603px) {
|
||||||
|
|
||||||
|
.overlay.scanner {
|
||||||
|
width: 640px;
|
||||||
|
height: 510px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-top: -275px;
|
||||||
|
margin-left: -340px;
|
||||||
|
background-color: #FFF;
|
||||||
|
-moz-box-shadow: none;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.scanner > .header {
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.scanner > .header h4, .overlay.scanner > .header .close {
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.scanner > .header .close {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
11583
www/dist/quagga.js
vendored
Normal file
11583
www/dist/quagga.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
www/dist/quagga.min.js
vendored
Normal file
1
www/dist/quagga.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
112
www/file_input.html
Normal file
112
www/file_input.html
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
|
||||||
|
|
||||||
|
<title>index</title>
|
||||||
|
<meta name="description" content=""/>
|
||||||
|
<meta name="author" content="Christoph Oberhofer"/>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/styles.css"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="headline">
|
||||||
|
<h1>QuaggaJS</h1>
|
||||||
|
|
||||||
|
<h2>An advanced barcode-scanner written in JavaScript</h2>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section id="container" class="container">
|
||||||
|
<h3>Working with file-input</h3>
|
||||||
|
|
||||||
|
<p>This example let's you select an image from your local filesystem.
|
||||||
|
QuaggaJS then tries to decode the barcode using
|
||||||
|
the preferred method (<strong>Code128</strong> or <strong>EAN</strong>).
|
||||||
|
There is no server interaction needed as the
|
||||||
|
file is simply accessed through the <a
|
||||||
|
href="http://www.w3.org/TR/file-upload/">File API</a>.</p>
|
||||||
|
|
||||||
|
<p>This also works great on a wide range of mobile-phones where the camera
|
||||||
|
access through <code>getUserMedia</code> is still very limited.</p>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<fieldset class="input-group">
|
||||||
|
<input type="file" accept="image/*" capture="camera"/>
|
||||||
|
<button>Rerun</button>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="reader-config-group">
|
||||||
|
<label>
|
||||||
|
<span>Barcode-Type</span>
|
||||||
|
<select name="decoder_readers">
|
||||||
|
<option value="code_128" selected="selected">Code 128</option>
|
||||||
|
<option value="code_39">Code 39</option>
|
||||||
|
<option value="code_39_vin">Code 39 VIN</option>
|
||||||
|
<option value="ean">EAN</option>
|
||||||
|
<option value="ean_extended">EAN-extended</option>
|
||||||
|
<option value="ean_8">EAN-8</option>
|
||||||
|
<option value="upc">UPC</option>
|
||||||
|
<option value="upc_e">UPC-E</option>
|
||||||
|
<option value="codabar">Codabar</option>
|
||||||
|
<option value="i2of5">Interleaved 2 of 5</option>
|
||||||
|
<option value="2of5">Standard 2 of 5</option>
|
||||||
|
<option value="code_93">Code 93</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Resolution (long side)</span>
|
||||||
|
<select name="input-stream_size">
|
||||||
|
<option value="320">320px</option>
|
||||||
|
<option value="640">640px</option>
|
||||||
|
<option selected="selected" value="800">800px</option>
|
||||||
|
<option value="1280">1280px</option>
|
||||||
|
<option value="1600">1600px</option>
|
||||||
|
<option value="1920">1920px</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Patch-Size</span>
|
||||||
|
<select name="locator_patch-size">
|
||||||
|
<option value="x-small">x-small</option>
|
||||||
|
<option value="small">small</option>
|
||||||
|
<option value="medium">medium</option>
|
||||||
|
<option selected="selected" value="large">large</option>
|
||||||
|
<option value="x-large">x-large</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Half-Sample</span>
|
||||||
|
<input type="checkbox" name="locator_half-sample" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Single Channel</span>
|
||||||
|
<input type="checkbox" name="input-stream_single-channel" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Workers</span>
|
||||||
|
<select name="numOfWorkers">
|
||||||
|
<option value="0">0</option>
|
||||||
|
<option selected="selected" value="1">1</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<div id="result_strip">
|
||||||
|
<ul class="thumbnails"></ul>
|
||||||
|
</div>
|
||||||
|
<div id="interactive" class="viewport"></div>
|
||||||
|
<div id="debug" class="detection"></div>
|
||||||
|
</section>
|
||||||
|
<footer>
|
||||||
|
<p>
|
||||||
|
© Copyright by Christoph Oberhofer
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
<script src="vendor/jquery-1.9.0.min.js" type="text/javascript"></script>
|
||||||
|
<script src="../dist/quagga.js" type="text/javascript"></script>
|
||||||
|
<script src="file_input.js" type="text/javascript"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
186
www/file_input.js
Normal file
186
www/file_input.js
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
$(function() {
|
||||||
|
var App = {
|
||||||
|
init: function() {
|
||||||
|
App.attachListeners();
|
||||||
|
},
|
||||||
|
attachListeners: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$(".controls input[type=file]").on("change", function(e) {
|
||||||
|
if (e.target.files && e.target.files.length) {
|
||||||
|
App.decode(URL.createObjectURL(e.target.files[0]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".controls button").on("click", function(e) {
|
||||||
|
var input = document.querySelector(".controls input[type=file]");
|
||||||
|
if (input.files && input.files.length) {
|
||||||
|
App.decode(URL.createObjectURL(input.files[0]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".controls .reader-config-group").on("change", "input, select", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var $target = $(e.target),
|
||||||
|
value = $target.attr("type") === "checkbox" ? $target.prop("checked") : $target.val(),
|
||||||
|
name = $target.attr("name"),
|
||||||
|
state = self._convertNameToState(name);
|
||||||
|
|
||||||
|
console.log("Value of "+ state + " changed to " + value);
|
||||||
|
self.setState(state, value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_accessByPath: function(obj, path, val) {
|
||||||
|
var parts = path.split('.'),
|
||||||
|
depth = parts.length,
|
||||||
|
setter = (typeof val !== "undefined") ? true : false;
|
||||||
|
|
||||||
|
return parts.reduce(function(o, key, i) {
|
||||||
|
if (setter && (i + 1) === depth) {
|
||||||
|
o[key] = val;
|
||||||
|
}
|
||||||
|
return key in o ? o[key] : {};
|
||||||
|
}, obj);
|
||||||
|
},
|
||||||
|
_convertNameToState: function(name) {
|
||||||
|
return name.replace("_", ".").split("-").reduce(function(result, value) {
|
||||||
|
return result + value.charAt(0).toUpperCase() + value.substring(1);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
detachListeners: function() {
|
||||||
|
$(".controls input[type=file]").off("change");
|
||||||
|
$(".controls .reader-config-group").off("change", "input, select");
|
||||||
|
$(".controls button").off("click");
|
||||||
|
},
|
||||||
|
decode: function(src) {
|
||||||
|
var self = this,
|
||||||
|
config = $.extend({}, self.state, {src: src});
|
||||||
|
|
||||||
|
Quagga.decodeSingle(config, function(result) {});
|
||||||
|
},
|
||||||
|
setState: function(path, value) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (typeof self._accessByPath(self.inputMapper, path) === "function") {
|
||||||
|
value = self._accessByPath(self.inputMapper, path)(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
self._accessByPath(self.state, path, value);
|
||||||
|
|
||||||
|
console.log(JSON.stringify(self.state));
|
||||||
|
App.detachListeners();
|
||||||
|
App.init();
|
||||||
|
},
|
||||||
|
inputMapper: {
|
||||||
|
inputStream: {
|
||||||
|
size: function(value){
|
||||||
|
return parseInt(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numOfWorkers: function(value) {
|
||||||
|
return parseInt(value);
|
||||||
|
},
|
||||||
|
decoder: {
|
||||||
|
readers: function(value) {
|
||||||
|
if (value === 'ean_extended') {
|
||||||
|
return [{
|
||||||
|
format: "ean_reader",
|
||||||
|
config: {
|
||||||
|
supplements: [
|
||||||
|
'ean_5_reader', 'ean_2_reader'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return [{
|
||||||
|
format: value + "_reader",
|
||||||
|
config: {}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
inputStream: {
|
||||||
|
size: 800,
|
||||||
|
singleChannel: false
|
||||||
|
},
|
||||||
|
locator: {
|
||||||
|
patchSize: "medium",
|
||||||
|
halfSample: true
|
||||||
|
},
|
||||||
|
decoder: {
|
||||||
|
readers: [{
|
||||||
|
format: "code_128_reader",
|
||||||
|
config: {}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
locate: true,
|
||||||
|
src: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
App.init();
|
||||||
|
|
||||||
|
function calculateRectFromArea(canvas, area) {
|
||||||
|
var canvasWidth = canvas.width,
|
||||||
|
canvasHeight = canvas.height,
|
||||||
|
top = parseInt(area.top)/100,
|
||||||
|
right = parseInt(area.right)/100,
|
||||||
|
bottom = parseInt(area.bottom)/100,
|
||||||
|
left = parseInt(area.left)/100;
|
||||||
|
|
||||||
|
top *= canvasHeight;
|
||||||
|
right = canvasWidth - canvasWidth*right;
|
||||||
|
bottom = canvasHeight - canvasHeight*bottom;
|
||||||
|
left *= canvasWidth;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: left,
|
||||||
|
y: top,
|
||||||
|
width: right - left,
|
||||||
|
height: bottom - top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Quagga.onProcessed(function(result) {
|
||||||
|
var drawingCtx = Quagga.canvas.ctx.overlay,
|
||||||
|
drawingCanvas = Quagga.canvas.dom.overlay,
|
||||||
|
area;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
if (result.boxes) {
|
||||||
|
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
|
||||||
|
result.boxes.filter(function (box) {
|
||||||
|
return box !== result.box;
|
||||||
|
}).forEach(function (box) {
|
||||||
|
Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "green", lineWidth: 2});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.box) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.box, {x: 0, y: 1}, drawingCtx, {color: "#00F", lineWidth: 2});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.codeResult && result.codeResult.code) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.line, {x: 'x', y: 'y'}, drawingCtx, {color: 'red', lineWidth: 3});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.state.inputStream.area) {
|
||||||
|
area = calculateRectFromArea(drawingCanvas, App.state.inputStream.area);
|
||||||
|
drawingCtx.strokeStyle = "#0F0";
|
||||||
|
drawingCtx.strokeRect(area.x, area.y, area.width, area.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Quagga.onDetected(function(result) {
|
||||||
|
var code = result.codeResult.code,
|
||||||
|
$node,
|
||||||
|
canvas = Quagga.canvas.dom.image;
|
||||||
|
|
||||||
|
$node = $('<li><div class="thumbnail"><div class="imgWrapper"><img /></div><div class="caption"><h4 class="code"></h4></div></div></li>');
|
||||||
|
$node.find("img").attr("src", canvas.toDataURL());
|
||||||
|
$node.find("h4.code").html(code);
|
||||||
|
$("#result_strip ul.thumbnails").prepend($node);
|
||||||
|
});
|
||||||
|
});
|
||||||
110
www/html_lama/css/index.css
Normal file
110
www/html_lama/css/index.css
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
* {
|
||||||
|
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
|
||||||
|
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
|
||||||
|
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
|
||||||
|
background-color:#E4E4E4;
|
||||||
|
background-image:linear-gradient(to bottom, #A7A7A7 0%, #E4E4E4 51%);
|
||||||
|
font-family: system-ui, -apple-system, -apple-system-font, 'Segoe UI', 'Roboto', sans-serif;
|
||||||
|
font-size:12px;
|
||||||
|
height:100vh;
|
||||||
|
margin:0px;
|
||||||
|
padding:0px;
|
||||||
|
/* Padding to avoid the "unsafe" areas behind notches in the screen */
|
||||||
|
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
|
||||||
|
text-transform:uppercase;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Portrait layout (default) */
|
||||||
|
.app {
|
||||||
|
background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
|
||||||
|
position:absolute; /* position in the center of the screen */
|
||||||
|
left:50%;
|
||||||
|
top:50%;
|
||||||
|
height:50px; /* text area height */
|
||||||
|
width:225px; /* text area width */
|
||||||
|
text-align:center;
|
||||||
|
padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
|
||||||
|
margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
|
||||||
|
/* offset horizontal: half of text area width */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Landscape layout (with min-width) */
|
||||||
|
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
|
||||||
|
.app {
|
||||||
|
background-position:left center;
|
||||||
|
padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
|
||||||
|
margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
|
||||||
|
/* offset horizontal: half of image width and text area width */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size:24px;
|
||||||
|
font-weight:normal;
|
||||||
|
margin:0px;
|
||||||
|
overflow:visible;
|
||||||
|
padding:0px;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event {
|
||||||
|
border-radius:4px;
|
||||||
|
color:#FFFFFF;
|
||||||
|
font-size:12px;
|
||||||
|
margin:0px 30px;
|
||||||
|
padding:2px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event.listening {
|
||||||
|
background-color:#333333;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event.received {
|
||||||
|
background-color:#4B946A;
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#deviceready.ready .event.listening { display: none; }
|
||||||
|
#deviceready.ready .event.received { display: block; }
|
||||||
|
|
||||||
|
@keyframes fade {
|
||||||
|
from { opacity: 1.0; }
|
||||||
|
50% { opacity: 0.4; }
|
||||||
|
to { opacity: 1.0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.blink {
|
||||||
|
animation:fade 3000ms infinite;
|
||||||
|
-webkit-animation:fade 3000ms infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media screen and (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
background-image:linear-gradient(to bottom, #585858 0%, #1B1B1B 51%);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
www/html_lama/img/logo.png
Normal file
BIN
www/html_lama/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
51
www/html_lama/index.html
Normal file
51
www/html_lama/index.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<!--
|
||||||
|
Customize this policy to fit your own app's needs. For more guidance, see:
|
||||||
|
https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
|
||||||
|
Some notes:
|
||||||
|
* gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
|
||||||
|
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
|
||||||
|
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
|
||||||
|
* Enable inline JS: add 'unsafe-inline' to default-src
|
||||||
|
-->
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
|
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<link rel="stylesheet" href="css/index.css">
|
||||||
|
<title>Hello World</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="app">
|
||||||
|
<h1>Apache Cordova</h1>
|
||||||
|
<div id="deviceready" class="blink">
|
||||||
|
<p class="event listening">Connecting to Device</p>
|
||||||
|
<p class="event received">Device is Ready</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="cordova.js"></script>
|
||||||
|
<script src="js/index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
29
www/html_lama/js/index.js
Normal file
29
www/html_lama/js/index.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Wait for the deviceready event before using any of Cordova's device APIs.
|
||||||
|
// See https://cordova.apache.org/docs/en/latest/cordova/events/events.html#deviceready
|
||||||
|
document.addEventListener('deviceready', onDeviceReady, false);
|
||||||
|
|
||||||
|
function onDeviceReady() {
|
||||||
|
// Cordova is now initialized. Have fun!
|
||||||
|
|
||||||
|
console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
|
||||||
|
document.getElementById('deviceready').classList.add('ready');
|
||||||
|
}
|
||||||
126
www/index.html
Normal file
126
www/index.html
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
|
|
||||||
|
<title>index</title>
|
||||||
|
<meta name="description" content="" />
|
||||||
|
<meta name="author" content="Christoph Oberhofer" />
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/styles.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="headline">
|
||||||
|
<h1>QuaggaJS</h1>
|
||||||
|
<h2>An advanced barcode-scanner written in JavaScript</h2>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section id="container" class="container">
|
||||||
|
<h3>The user's camera</h3>
|
||||||
|
<p>If your platform supports the <strong>getUserMedia</strong> API call, you can try the real-time locating and decoding features.
|
||||||
|
Simply allow the page to access your web-cam and point it to a barcode. You can switch between <strong>Code128</strong>
|
||||||
|
and <strong>EAN</strong> to test different scenarios.
|
||||||
|
It works best if your camera has built-in auto-focus.
|
||||||
|
</p>
|
||||||
|
<div class="controls">
|
||||||
|
<fieldset class="input-group">
|
||||||
|
<button class="stop">Stop</button>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="reader-config-group">
|
||||||
|
<label>
|
||||||
|
<span>Barcode-Type</span>
|
||||||
|
<select name="decoder_readers">
|
||||||
|
<option value="code_128" selected="selected">Code 128</option>
|
||||||
|
<option value="code_39">Code 39</option>
|
||||||
|
<option value="code_39_vin">Code 39 VIN</option>
|
||||||
|
<option value="ean">EAN</option>
|
||||||
|
<option value="ean_extended">EAN-extended</option>
|
||||||
|
<option value="ean_8">EAN-8</option>
|
||||||
|
<option value="upc">UPC</option>
|
||||||
|
<option value="upc_e">UPC-E</option>
|
||||||
|
<option value="codabar">Codabar</option>
|
||||||
|
<option value="i2of5">Interleaved 2 of 5</option>
|
||||||
|
<option value="2of5">Standard 2 of 5</option>
|
||||||
|
<option value="code_93">Code 93</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Resolution (width)</span>
|
||||||
|
<select name="input-stream_constraints">
|
||||||
|
<option value="320x240">320px</option>
|
||||||
|
<option selected="selected" value="640x480">640px</option>
|
||||||
|
<option value="800x600">800px</option>
|
||||||
|
<option value="1280x720">1280px</option>
|
||||||
|
<option value="1600x960">1600px</option>
|
||||||
|
<option value="1920x1080">1920px</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Patch-Size</span>
|
||||||
|
<select name="locator_patch-size">
|
||||||
|
<option value="x-small">x-small</option>
|
||||||
|
<option value="small">small</option>
|
||||||
|
<option selected="selected" value="medium">medium</option>
|
||||||
|
<option value="large">large</option>
|
||||||
|
<option value="x-large">x-large</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Half-Sample</span>
|
||||||
|
<input type="checkbox" checked="checked" name="locator_half-sample" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Workers</span>
|
||||||
|
<select name="numOfWorkers">
|
||||||
|
<option value="0">0</option>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="2">2</option>
|
||||||
|
<option selected="selected" value="4">4</option>
|
||||||
|
<option value="8">8</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<span>Camera</span>
|
||||||
|
<select name="input-stream_constraints" id="deviceSelection">
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<button onclick ='hidupkan_kembali()'>heheheh</button>
|
||||||
|
<label style="display: none">
|
||||||
|
<span>Zoom</span>
|
||||||
|
<select name="settings_zoom"></select>
|
||||||
|
</label>
|
||||||
|
<label style="display: none">
|
||||||
|
<span>Torch</span>
|
||||||
|
<input type="checkbox" name="settings_torch" />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<div id="result_strip">
|
||||||
|
<ul class="thumbnails"></ul>
|
||||||
|
<ul class="collector"></ul>
|
||||||
|
</div>
|
||||||
|
<div id="interactive" class="viewport"></div>
|
||||||
|
</section>
|
||||||
|
<footer>
|
||||||
|
<p>
|
||||||
|
© Made with ❤️ by Christoph Oberhofer
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="vendor/jquery-1.9.0.min.js" type="text/javascript"></script>
|
||||||
|
<script src="http://webrtc.github.io/adapter/adapter-latest.js" type="text/javascript"></script>
|
||||||
|
<script src="cordova.js"></script>
|
||||||
|
<script src="index.js"></script>
|
||||||
|
<script src="dist/quagga.js" type="text/javascript"></script>
|
||||||
|
<script src="live_w_locator.js" type="text/javascript"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function hidupkan_kembali() {
|
||||||
|
App.init();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
www/index.js
Normal file
33
www/index.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Wait for the deviceready event before using any of Cordova's device APIs.
|
||||||
|
// See https://cordova.apache.org/docs/en/latest/cordova/events/events.html#deviceready
|
||||||
|
document.addEventListener('deviceready', onDeviceReady, false);
|
||||||
|
// var permissions = cordova.plugins.permissions; permissions.checkPermission(permissions.CAMERA, (res) => { if (!res.hasPermission) { permissions.requestPermission(permissions.CAMERA, open());
|
||||||
|
|
||||||
|
|
||||||
|
function onDeviceReady() {
|
||||||
|
// Cordova is now initialized. Have fun!
|
||||||
|
console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
|
||||||
|
// var permissions = cordova.plugins.permissions; permissions.checkPermission(permissions.CAMERA, (res) => { if (!res.hasPermission) { permissions.requestPermission(permissions.CAMERA, open());
|
||||||
|
App.init();
|
||||||
|
// console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
|
||||||
|
// document.getElementById('deviceready').classList.add('ready');
|
||||||
|
}
|
||||||
299
www/live_w_locator.js
Normal file
299
www/live_w_locator.js
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
// $(function() {
|
||||||
|
var resultCollector = Quagga.ResultCollector.create({
|
||||||
|
capture: true,
|
||||||
|
capacity: 20,
|
||||||
|
blacklist: [{
|
||||||
|
code: "WIWV8ETQZ1", format: "code_93"
|
||||||
|
}, {
|
||||||
|
code: "EH3C-%GU23RK3", format: "code_93"
|
||||||
|
}, {
|
||||||
|
code: "O308SIHQOXN5SA/PJ", format: "code_93"
|
||||||
|
}, {
|
||||||
|
code: "DG7Q$TV8JQ/EN", format: "code_93"
|
||||||
|
}, {
|
||||||
|
code: "VOFD1DB5A.1F6QU", format: "code_93"
|
||||||
|
}, {
|
||||||
|
code: "4SO64P4X8 U4YUU1T-", format: "code_93"
|
||||||
|
}],
|
||||||
|
filter: function(codeResult) {
|
||||||
|
// only store results which match this constraint
|
||||||
|
// e.g.: codeResult
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var App = {
|
||||||
|
init: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
Quagga.init(this.state, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return self.handleError(err);
|
||||||
|
}
|
||||||
|
//Quagga.registerResultCollector(resultCollector);
|
||||||
|
App.attachListeners();
|
||||||
|
App.checkCapabilities();
|
||||||
|
Quagga.start();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleError: function(err) {
|
||||||
|
console.log(err);
|
||||||
|
},
|
||||||
|
checkCapabilities: function() {
|
||||||
|
var track = Quagga.CameraAccess.getActiveTrack();
|
||||||
|
var capabilities = {};
|
||||||
|
if (typeof track.getCapabilities === 'function') {
|
||||||
|
capabilities = track.getCapabilities();
|
||||||
|
}
|
||||||
|
this.applySettingsVisibility('zoom', capabilities.zoom);
|
||||||
|
this.applySettingsVisibility('torch', capabilities.torch);
|
||||||
|
},
|
||||||
|
updateOptionsForMediaRange: function(node, range) {
|
||||||
|
console.log('updateOptionsForMediaRange', node, range);
|
||||||
|
var NUM_STEPS = 6;
|
||||||
|
var stepSize = (range.max - range.min) / NUM_STEPS;
|
||||||
|
var option;
|
||||||
|
var value;
|
||||||
|
while (node.firstChild) {
|
||||||
|
node.removeChild(node.firstChild);
|
||||||
|
}
|
||||||
|
for (var i = 0; i <= NUM_STEPS; i++) {
|
||||||
|
value = range.min + (stepSize * i);
|
||||||
|
option = document.createElement('option');
|
||||||
|
option.value = value;
|
||||||
|
option.innerHTML = value;
|
||||||
|
node.appendChild(option);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applySettingsVisibility: function(setting, capability) {
|
||||||
|
// depending on type of capability
|
||||||
|
if (typeof capability === 'boolean') {
|
||||||
|
var node = document.querySelector('input[name="settings_' + setting + '"]');
|
||||||
|
if (node) {
|
||||||
|
node.parentNode.style.display = capability ? 'block' : 'none';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (window.MediaSettingsRange && capability instanceof window.MediaSettingsRange) {
|
||||||
|
var node = document.querySelector('select[name="settings_' + setting + '"]');
|
||||||
|
if (node) {
|
||||||
|
this.updateOptionsForMediaRange(node, capability);
|
||||||
|
node.parentNode.style.display = 'block';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initCameraSelection: function(){
|
||||||
|
var streamLabel = Quagga.CameraAccess.getActiveStreamLabel();
|
||||||
|
|
||||||
|
return Quagga.CameraAccess.enumerateVideoDevices()
|
||||||
|
.then(function(devices) {
|
||||||
|
function pruneText(text) {
|
||||||
|
return text.length > 30 ? text.substr(0, 30) : text;
|
||||||
|
}
|
||||||
|
var $deviceSelection = document.getElementById("deviceSelection");
|
||||||
|
while ($deviceSelection.firstChild) {
|
||||||
|
$deviceSelection.removeChild($deviceSelection.firstChild);
|
||||||
|
}
|
||||||
|
devices.forEach(function(device) {
|
||||||
|
var $option = document.createElement("option");
|
||||||
|
$option.value = device.deviceId || device.id;
|
||||||
|
$option.appendChild(document.createTextNode(pruneText(device.label || device.deviceId || device.id)));
|
||||||
|
$option.selected = streamLabel === device.label;
|
||||||
|
$deviceSelection.appendChild($option);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
attachListeners: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.initCameraSelection();
|
||||||
|
$(".controls").on("click", "button.stop", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
Quagga.stop();
|
||||||
|
self._printCollectedResults();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".controls .reader-config-group").on("change", "input, select", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var $target = $(e.target),
|
||||||
|
value = $target.attr("type") === "checkbox" ? $target.prop("checked") : $target.val(),
|
||||||
|
name = $target.attr("name"),
|
||||||
|
state = self._convertNameToState(name);
|
||||||
|
|
||||||
|
console.log("Value of "+ state + " changed to " + value);
|
||||||
|
self.setState(state, value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_printCollectedResults: function() {
|
||||||
|
var results = resultCollector.getResults(),
|
||||||
|
$ul = $("#result_strip ul.collector");
|
||||||
|
|
||||||
|
results.forEach(function(result) {
|
||||||
|
var $li = $('<li><div class="thumbnail"><div class="imgWrapper"><img /></div><div class="caption"><h4 class="code"></h4></div></div></li>');
|
||||||
|
|
||||||
|
$li.find("img").attr("src", result.frame);
|
||||||
|
$li.find("h4.code").html(result.codeResult.code + " (" + result.codeResult.format + ")");
|
||||||
|
$ul.prepend($li);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_accessByPath: function(obj, path, val) {
|
||||||
|
var parts = path.split('.'),
|
||||||
|
depth = parts.length,
|
||||||
|
setter = (typeof val !== "undefined") ? true : false;
|
||||||
|
|
||||||
|
return parts.reduce(function(o, key, i) {
|
||||||
|
if (setter && (i + 1) === depth) {
|
||||||
|
if (typeof o[key] === "object" && typeof val === "object") {
|
||||||
|
Object.assign(o[key], val);
|
||||||
|
} else {
|
||||||
|
o[key] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return key in o ? o[key] : {};
|
||||||
|
}, obj);
|
||||||
|
},
|
||||||
|
_convertNameToState: function(name) {
|
||||||
|
return name.replace("_", ".").split("-").reduce(function(result, value) {
|
||||||
|
return result + value.charAt(0).toUpperCase() + value.substring(1);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
detachListeners: function() {
|
||||||
|
$(".controls").off("click", "button.stop");
|
||||||
|
$(".controls .reader-config-group").off("change", "input, select");
|
||||||
|
},
|
||||||
|
applySetting: function(setting, value) {
|
||||||
|
var track = Quagga.CameraAccess.getActiveTrack();
|
||||||
|
if (track && typeof track.getCapabilities === 'function') {
|
||||||
|
switch (setting) {
|
||||||
|
case 'zoom':
|
||||||
|
return track.applyConstraints({advanced: [{zoom: parseFloat(value)}]});
|
||||||
|
case 'torch':
|
||||||
|
return track.applyConstraints({advanced: [{torch: !!value}]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setState: function(path, value) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (typeof self._accessByPath(self.inputMapper, path) === "function") {
|
||||||
|
value = self._accessByPath(self.inputMapper, path)(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.startsWith('settings.')) {
|
||||||
|
var setting = path.substring(9);
|
||||||
|
return self.applySetting(setting, value);
|
||||||
|
}
|
||||||
|
self._accessByPath(self.state, path, value);
|
||||||
|
|
||||||
|
//console.log(JSON.stringify(self.state));
|
||||||
|
App.detachListeners();
|
||||||
|
Quagga.stop();
|
||||||
|
App.init();
|
||||||
|
},
|
||||||
|
inputMapper: {
|
||||||
|
inputStream: {
|
||||||
|
constraints: function(value){
|
||||||
|
if (/^(\d+)x(\d+)$/.test(value)) {
|
||||||
|
var values = value.split('x');
|
||||||
|
return {
|
||||||
|
width: {min: parseInt(values[0])},
|
||||||
|
height: {min: parseInt(values[1])}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
deviceId: value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numOfWorkers: function(value) {
|
||||||
|
return parseInt(value);
|
||||||
|
},
|
||||||
|
decoder: {
|
||||||
|
readers: function(value) {
|
||||||
|
if (value === 'ean_extended') {
|
||||||
|
return [{
|
||||||
|
format: "ean_reader",
|
||||||
|
config: {
|
||||||
|
supplements: [
|
||||||
|
'ean_5_reader', 'ean_2_reader'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return [{
|
||||||
|
format: value + "_reader",
|
||||||
|
config: {}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
inputStream: {
|
||||||
|
type : "LiveStream",
|
||||||
|
constraints: {
|
||||||
|
width: {min: 640},
|
||||||
|
height: {min: 480},
|
||||||
|
facingMode: "environment",
|
||||||
|
aspectRatio: {min: 1, max: 2}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
locator: {
|
||||||
|
patchSize: "medium",
|
||||||
|
halfSample: true
|
||||||
|
},
|
||||||
|
numOfWorkers: 2,
|
||||||
|
frequency: 10,
|
||||||
|
decoder: {
|
||||||
|
readers : [{
|
||||||
|
format: "ean_reader",
|
||||||
|
config: {}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
locate: true
|
||||||
|
},
|
||||||
|
lastResult : null
|
||||||
|
};
|
||||||
|
|
||||||
|
App.init();
|
||||||
|
|
||||||
|
Quagga.onProcessed(function(result) {
|
||||||
|
|
||||||
|
var drawingCtx = Quagga.canvas.ctx.overlay,
|
||||||
|
drawingCanvas = Quagga.canvas.dom.overlay;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
if (result.boxes) {
|
||||||
|
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
|
||||||
|
result.boxes.filter(function (box) {
|
||||||
|
return box !== result.box;
|
||||||
|
}).forEach(function (box) {
|
||||||
|
Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "green", lineWidth: 2});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.box) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.box, {x: 0, y: 1}, drawingCtx, {color: "#00F", lineWidth: 2});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.codeResult && result.codeResult.code) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.line, {x: 'x', y: 'y'}, drawingCtx, {color: 'red', lineWidth: 3});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Quagga.onDetected(function(result) {
|
||||||
|
var code = result.codeResult.code;
|
||||||
|
console.log(code);
|
||||||
|
Quagga.stop();
|
||||||
|
if (App.lastResult !== code) {
|
||||||
|
App.lastResult = code;
|
||||||
|
var $node = null, canvas = Quagga.canvas.dom.image;
|
||||||
|
|
||||||
|
$node = $('<li><div class="thumbnail"><div class="imgWrapper"><img /></div><div class="caption"><h4 class="code"></h4></div></div></li>');
|
||||||
|
$node.find("img").attr("src", canvas.toDataURL());
|
||||||
|
$node.find("h4.code").html(code);
|
||||||
|
$("#result_strip ul.thumbnails").prepend($node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// });
|
||||||
27
www/node-test-with-buffer.js
Normal file
27
www/node-test-with-buffer.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
var Quagga = require('../lib/quagga').default;
|
||||||
|
|
||||||
|
var buffer = require('fs').readFileSync('../test/fixtures/code_128/image-001.jpg');
|
||||||
|
|
||||||
|
decode(buffer);
|
||||||
|
function decode(buff){
|
||||||
|
Quagga.decodeSingle({
|
||||||
|
src: buff,
|
||||||
|
numOfWorkers: 0,
|
||||||
|
inputStream: {
|
||||||
|
mime: "image/jpeg",
|
||||||
|
size: 800,
|
||||||
|
area: {
|
||||||
|
top: "10%",
|
||||||
|
right: "5%",
|
||||||
|
left: "5%",
|
||||||
|
bottom: "10%"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, function(result) {
|
||||||
|
if (result.codeResult) {
|
||||||
|
console.log("result", result.codeResult.code);
|
||||||
|
} else {
|
||||||
|
console.log("not detected");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
21
www/node-test.js
Normal file
21
www/node-test.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
var Quagga = require('../lib/quagga').default;
|
||||||
|
|
||||||
|
Quagga.decodeSingle({
|
||||||
|
src: "../test/fixtures/code_128/image-001.jpg",
|
||||||
|
numOfWorkers: 0,
|
||||||
|
inputStream: {
|
||||||
|
size: 800,
|
||||||
|
area: {
|
||||||
|
top: "10%",
|
||||||
|
right: "5%",
|
||||||
|
left: "5%",
|
||||||
|
bottom: "10%"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, function(result) {
|
||||||
|
if(result.codeResult) {
|
||||||
|
console.log("result", result.codeResult.code);
|
||||||
|
} else {
|
||||||
|
console.log("not detected");
|
||||||
|
}
|
||||||
|
});
|
||||||
69
www/static_images.html
Normal file
69
www/static_images.html
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
|
|
||||||
|
<title>index</title>
|
||||||
|
<meta name="description" content="" />
|
||||||
|
<meta name="author" content="Christoph Oberhofer" />
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0" />
|
||||||
|
<link href='http://fonts.googleapis.com/css?family=Ubuntu:400,700,300' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/styles.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="headline">
|
||||||
|
<h1>QuaggaJS</h1>
|
||||||
|
<h2>An advanced barcode-scanner written in JavaScript</h2>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section id="container" class="container">
|
||||||
|
<h3>Working with static images</h3>
|
||||||
|
<p>This examples uses static image files as input which are loaded from the server on startup.
|
||||||
|
The locating and decoding process takes place inside the browser.
|
||||||
|
Hit the <strong>next</strong> button to try a different image. You can also switch between
|
||||||
|
two different test-sets. Each of those contains 10 images, demonstrating the capabilities of decoding
|
||||||
|
<strong>Code128</strong> and <strong>EAN</strong> encoded barcodes.
|
||||||
|
</p>
|
||||||
|
<div class="controls">
|
||||||
|
<fieldset class="input-group">
|
||||||
|
<button class="next">Next</button>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="reader-config-group">
|
||||||
|
<span>Barcode-Type</span>
|
||||||
|
<select name="decoder_readers;input-stream_src">
|
||||||
|
<option value="code_128" selected="selected">Code 128</option>
|
||||||
|
<option value="code_39">Code 39</option>
|
||||||
|
<option value="code_39_vin">Code 39 VIN</option>
|
||||||
|
<option value="ean">EAN</option>
|
||||||
|
<option value="ean_extended">EAN-extended</option>
|
||||||
|
<option value="ean_8">EAN-8</option>
|
||||||
|
<option value="upc">UPC</option>
|
||||||
|
<option value="upc_e">UPC-E</option>
|
||||||
|
<option value="codabar">Codabar</option>
|
||||||
|
<option value="i2of5">I2of5</option>
|
||||||
|
<option value="i2of5">Interleaved 2 of 5</option>
|
||||||
|
<option value="2of5">Standard 2 of 5</option>
|
||||||
|
<option value="code_93">Code 93</option>
|
||||||
|
</select>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<div id="result_strip">
|
||||||
|
<ul class="thumbnails"></ul>
|
||||||
|
</div>
|
||||||
|
<div id="interactive" class="viewport"></div>
|
||||||
|
<div id="debug" class="detection"></div>
|
||||||
|
</section>
|
||||||
|
<footer>
|
||||||
|
<p>
|
||||||
|
© Copyright by Christoph Oberhofer
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
<script src="vendor/jquery-1.9.0.min.js" type="text/javascript"></script>
|
||||||
|
<script src="../dist/quagga.js" type="text/javascript"></script>
|
||||||
|
<script src="static_images.js" type="text/javascript"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
170
www/static_images.js
Normal file
170
www/static_images.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
$(function() {
|
||||||
|
var App = {
|
||||||
|
init: function() {
|
||||||
|
var config = this.config[this.state.decoder.readers[0].format] || this.config.default;
|
||||||
|
config = $.extend(true, {}, config, this.state);
|
||||||
|
Quagga.init(config, function() {
|
||||||
|
App.attachListeners();
|
||||||
|
Quagga.start();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
"default": {
|
||||||
|
inputStream: { name: "Test",
|
||||||
|
type: "ImageStream",
|
||||||
|
length: 10,
|
||||||
|
size: 800
|
||||||
|
},
|
||||||
|
locator: {
|
||||||
|
patchSize: "medium",
|
||||||
|
halfSample: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i2of5_reader": {
|
||||||
|
inputStream: {
|
||||||
|
size: 800,
|
||||||
|
type: "ImageStream",
|
||||||
|
length: 5
|
||||||
|
},
|
||||||
|
locator: {
|
||||||
|
patchSize: "small",
|
||||||
|
halfSample: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
attachListeners: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$(".controls").on("click", "button.next", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
Quagga.start();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".controls .reader-config-group").on("change", "input, select", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var $target = $(e.target),
|
||||||
|
value = $target.attr("type") === "checkbox" ? $target.prop("checked") : $target.val(),
|
||||||
|
name = $target.attr("name"),
|
||||||
|
states = self._convertNameToStates(name);
|
||||||
|
|
||||||
|
console.log("Value of "+ states + " changed to " + value);
|
||||||
|
self.setState(states, value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
detachListeners: function() {
|
||||||
|
$(".controls").off("click", "button.next");
|
||||||
|
$(".controls .reader-config-group").off("change", "input, select");
|
||||||
|
},
|
||||||
|
_accessByPath: function(obj, path, val) {
|
||||||
|
var parts = path.split('.'),
|
||||||
|
depth = parts.length,
|
||||||
|
setter = (typeof val !== "undefined") ? true : false;
|
||||||
|
|
||||||
|
return parts.reduce(function(o, key, i) {
|
||||||
|
if (setter && (i + 1) === depth) {
|
||||||
|
o[key] = val;
|
||||||
|
}
|
||||||
|
return key in o ? o[key] : {};
|
||||||
|
}, obj);
|
||||||
|
},
|
||||||
|
_convertNameToStates: function(names) {
|
||||||
|
return names.split(";").map(this._convertNameToState.bind(this));
|
||||||
|
},
|
||||||
|
_convertNameToState: function(name) {
|
||||||
|
return name.replace("_", ".").split("-").reduce(function(result, value) {
|
||||||
|
return result + value.charAt(0).toUpperCase() + value.substring(1);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setState: function(paths, value) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
paths.forEach(function(path) {
|
||||||
|
var mappedValue;
|
||||||
|
|
||||||
|
if (typeof self._accessByPath(self.inputMapper, path) === "function") {
|
||||||
|
mappedValue = self._accessByPath(self.inputMapper, path)(value);
|
||||||
|
}
|
||||||
|
self._accessByPath(self.state, path, mappedValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(JSON.stringify(self.state));
|
||||||
|
App.detachListeners();
|
||||||
|
Quagga.stop();
|
||||||
|
App.init();
|
||||||
|
},
|
||||||
|
inputMapper: {
|
||||||
|
decoder: {
|
||||||
|
readers: function(value) {
|
||||||
|
if (value === 'ean_extended') {
|
||||||
|
return [{
|
||||||
|
format: "ean_reader",
|
||||||
|
config: {
|
||||||
|
supplements: [
|
||||||
|
'ean_5_reader', 'ean_2_reader'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return [{
|
||||||
|
format: value + "_reader",
|
||||||
|
config: {}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inputStream: {
|
||||||
|
src: function(value) {
|
||||||
|
return "../test/fixtures/" + value + "/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
inputStream: {
|
||||||
|
src: "../test/fixtures/code_128/"
|
||||||
|
},
|
||||||
|
decoder : {
|
||||||
|
readers : [{
|
||||||
|
format: "code_128_reader",
|
||||||
|
config: {}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
App.init();
|
||||||
|
window.App = App;
|
||||||
|
|
||||||
|
Quagga.onProcessed(function(result) {
|
||||||
|
var drawingCtx = Quagga.canvas.ctx.overlay,
|
||||||
|
drawingCanvas = Quagga.canvas.dom.overlay;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
if (result.boxes) {
|
||||||
|
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
|
||||||
|
result.boxes.filter(function (box) {
|
||||||
|
return box !== result.box;
|
||||||
|
}).forEach(function (box) {
|
||||||
|
Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "green", lineWidth: 2});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.box) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.box, {x: 0, y: 1}, drawingCtx, {color: "#00F", lineWidth: 2});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.codeResult && result.codeResult.code) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.line, {x: 'x', y: 'y'}, drawingCtx, {color: 'red', lineWidth: 3});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Quagga.onDetected(function(result) {
|
||||||
|
var $node,
|
||||||
|
canvas = Quagga.canvas.dom.image,
|
||||||
|
detectedCode = result.codeResult.code;
|
||||||
|
|
||||||
|
$node = $('<li><div class="thumbnail"><div class="imgWrapper"><img /></div><div class="caption"><h4 class="code"></h4></div></div></li>');
|
||||||
|
$node.find("img").attr("src", canvas.toDataURL());
|
||||||
|
$node.find("h4.code").html(detectedCode);
|
||||||
|
$("#result_strip ul.thumbnails").prepend($node);
|
||||||
|
});
|
||||||
|
});
|
||||||
4
www/vendor/jquery-1.9.0.min.js
vendored
Normal file
4
www/vendor/jquery-1.9.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user