emblemscanner: worker wip
This commit is contained in:
parent
adb87f27b5
commit
450d4f7090
@ -91,6 +91,7 @@ Page({
|
|||||||
rule_zoom: -1,
|
rule_zoom: -1,
|
||||||
camera_rule: null,
|
camera_rule: null,
|
||||||
use_web_view: false,
|
use_web_view: false,
|
||||||
|
use_worker: false,
|
||||||
emblem_camera_url: null,
|
emblem_camera_url: null,
|
||||||
// State machine: loading_rules -> loading_qrtool -> init_camera -> scanning -> verifying -> result
|
// State machine: loading_rules -> loading_qrtool -> init_camera -> scanning -> verifying -> result
|
||||||
app_state: 'loading_rules', // 'loading_rules', 'loading_qrtool', 'init_camera', 'scanning', 'webview_scanning', 'verifying', 'result'
|
app_state: 'loading_rules', // 'loading_rules', 'loading_qrtool', 'init_camera', 'scanning', 'webview_scanning', 'verifying', 'result'
|
||||||
@ -154,15 +155,89 @@ Page({
|
|||||||
initializeSystem(enable_debug) {
|
initializeSystem(enable_debug) {
|
||||||
const systemInfo = get_system_info();
|
const systemInfo = get_system_info();
|
||||||
const phone_model = systemInfo.model;
|
const phone_model = systemInfo.model;
|
||||||
|
const use_worker = phone_model.toLowerCase().includes("iphone");
|
||||||
|
|
||||||
this.setData({
|
this.setData({
|
||||||
enable_debug,
|
enable_debug,
|
||||||
phone_model,
|
phone_model,
|
||||||
window_width: systemInfo.windowWidth,
|
window_width: systemInfo.windowWidth,
|
||||||
window_height: systemInfo.windowHeight
|
window_height: systemInfo.windowHeight,
|
||||||
|
use_worker: use_worker
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Phone model: ${phone_model}, Using native camera mode`);
|
console.log(`Phone model: ${phone_model}, Use worker: ${use_worker}`);
|
||||||
|
|
||||||
|
// Set up worker if needed (like camera.js)
|
||||||
|
if (use_worker) {
|
||||||
|
this.setupWorker();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up worker for iPhone processing like camera.js
|
||||||
|
*/
|
||||||
|
setupWorker() {
|
||||||
|
// Create worker with local worker file
|
||||||
|
this.worker = wx.createWorker('/pages/emblemscanner/worker/index.js');
|
||||||
|
|
||||||
|
this.worker.onMessage((msg) => {
|
||||||
|
console.log('Worker message:', msg.type);
|
||||||
|
|
||||||
|
if (msg.type === "result") {
|
||||||
|
const result = msg.res;
|
||||||
|
const processingTime = msg.processing_time;
|
||||||
|
|
||||||
|
// Update statistics
|
||||||
|
const newFramesProcessed = this.data.frames_processed + 1;
|
||||||
|
const newTotalTime = this.data.total_processing_time + processingTime;
|
||||||
|
const newAvgTime = Math.round(newTotalTime / newFramesProcessed);
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
frames_processed: newFramesProcessed,
|
||||||
|
total_processing_time: newTotalTime,
|
||||||
|
avg_processing_time_ms: newAvgTime,
|
||||||
|
last_frame_time_ms: Math.round(processingTime),
|
||||||
|
debug_last_result: result
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
// For worker, we need to trigger image collection when we find a good QR
|
||||||
|
if (result.ok && result.qrcode && result.valid_pattern && is_emblem_qr_pattern(result.qrcode)) {
|
||||||
|
this.addDebugMessage(`Worker QR detected: ${result.qrcode}`);
|
||||||
|
|
||||||
|
// Trigger zoom-in if function is set up
|
||||||
|
if (this.on_qr_found && !this.data.qr_found) {
|
||||||
|
this.on_qr_found();
|
||||||
|
this.setData({ qr_found: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request worker to submit image data
|
||||||
|
this.worker.postMessage({ type: "ready_to_submit" });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handleQRResult(result, this.lastWorkerFrame);
|
||||||
|
}
|
||||||
|
} else if (msg.type === "submit") {
|
||||||
|
// Handle submit message from worker (image data for upload)
|
||||||
|
const result = msg.res;
|
||||||
|
const imageData = msg.image_data;
|
||||||
|
if (imageData) {
|
||||||
|
const dataUrl = data_url_from_frame(imageData.width, imageData.height, new Uint8ClampedArray(imageData.data));
|
||||||
|
this.image_data_urls.push(dataUrl);
|
||||||
|
|
||||||
|
if (this.image_data_urls.length >= 3) {
|
||||||
|
this.addDebugMessage('3 good images collected via worker, starting verification');
|
||||||
|
this.startVerifying();
|
||||||
|
this.submitImageForVerification(this.image_data_urls, result.qrcode);
|
||||||
|
this.image_data_urls = []; // Reset for next scan
|
||||||
|
} else {
|
||||||
|
this.addDebugMessage(`Collected ${this.image_data_urls.length}/3 worker images`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addDebugMessage('Worker set up for iPhone processing');
|
||||||
},
|
},
|
||||||
|
|
||||||
loadCameraRules(max_zoom = null) {
|
loadCameraRules(max_zoom = null) {
|
||||||
@ -371,7 +446,7 @@ Page({
|
|||||||
* Camera frame callback - receives live camera frames
|
* Camera frame callback - receives live camera frames
|
||||||
*/
|
*/
|
||||||
onCameraFrame(frame) {
|
onCameraFrame(frame) {
|
||||||
// Only process frames when in camera scanning state and QRTool is ready
|
// Only process frames when in camera scanning state
|
||||||
if (this.data.app_state !== 'scanning') {
|
if (this.data.app_state !== 'scanning') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -386,10 +461,28 @@ Page({
|
|||||||
}
|
}
|
||||||
this.lastFrameTime = now;
|
this.lastFrameTime = now;
|
||||||
|
|
||||||
// Start timing frame processing
|
// Use worker for iPhone, direct processing for other devices
|
||||||
|
if (this.data.use_worker && this.worker) {
|
||||||
|
// Worker processing (iPhone)
|
||||||
|
this.lastWorkerFrame = frame; // Store for handleQRResult
|
||||||
|
this.worker.postMessage({
|
||||||
|
type: 'frame',
|
||||||
|
width: frame.width,
|
||||||
|
height: frame.height,
|
||||||
|
camera_sensitivity: this.data.camera_sensitivity
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Direct processing (other devices)
|
||||||
|
this.processFrameDirect(frame);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process frame directly (non-iPhone devices)
|
||||||
|
*/
|
||||||
|
processFrameDirect(frame) {
|
||||||
const processStart = Date.now();
|
const processStart = Date.now();
|
||||||
|
|
||||||
// Process frame data directly
|
|
||||||
try {
|
try {
|
||||||
const result = process_frame(frame.width, frame.height, frame.data, this.data.camera_sensitivity, this.data.enable_debug);
|
const result = process_frame(frame.width, frame.height, frame.data, this.data.camera_sensitivity, this.data.enable_debug);
|
||||||
|
|
||||||
|
|||||||
73
scanner/pages/emblemscanner/worker/index.js
Normal file
73
scanner/pages/emblemscanner/worker/index.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
console.log("hello from emblemscanner worker");
|
||||||
|
|
||||||
|
let qrtool = require('../qrtool.wx.js');
|
||||||
|
|
||||||
|
var qrtool_ready = false;
|
||||||
|
|
||||||
|
qrtool.onRuntimeInitialized = () => {
|
||||||
|
console.log("emblemscanner qrtool ready");
|
||||||
|
qrtool_ready = true;
|
||||||
|
worker.postMessage({
|
||||||
|
type: "ready",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var submit_message = null;
|
||||||
|
|
||||||
|
function handle_frame(data, width, height, camera_sensitivity) {
|
||||||
|
if (!qrtool_ready) {
|
||||||
|
console.log("qrtool not ready");
|
||||||
|
worker.postMessage({
|
||||||
|
type: "result",
|
||||||
|
res: {
|
||||||
|
ok: false,
|
||||||
|
err: "qrtool not ready",
|
||||||
|
},
|
||||||
|
processing_time: Date.now() - begin,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const begin = Date.now();
|
||||||
|
var uca = new Uint8ClampedArray(data);
|
||||||
|
var buf = qrtool._malloc(uca.length * uca.BYTES_PER_ELEMENT);
|
||||||
|
qrtool.HEAPU8.set(uca, buf);
|
||||||
|
var r = qrtool.ccall('qrtool_angle', 'string', ['number', 'number', 'number', 'number', 'number'], [buf, width, height, 0, camera_sensitivity]);
|
||||||
|
qrtool._free(buf);
|
||||||
|
console.log("emblemscanner worker r:", r);
|
||||||
|
var res = JSON.parse(r);
|
||||||
|
worker.postMessage({
|
||||||
|
type: "result",
|
||||||
|
res,
|
||||||
|
processing_time: Date.now() - begin,
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
// Since image_data takes seconds to serialize, send it in a separate
|
||||||
|
// message to the UI can update with the good news
|
||||||
|
submit_message = {
|
||||||
|
type: "submit",
|
||||||
|
res,
|
||||||
|
image_data: { data, width, height },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.onMessage((msg) => {
|
||||||
|
console.log("emblemscanner worker got message", msg.type);
|
||||||
|
switch (msg.type) {
|
||||||
|
case "frame":
|
||||||
|
try {
|
||||||
|
const data = worker.getCameraFrameData();
|
||||||
|
if (data) {
|
||||||
|
handle_frame(data, msg.width, msg.height, msg.camera_sensitivity);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ready_to_submit":
|
||||||
|
worker.postMessage(submit_message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("Unknown message type:", msg.data.type);
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user