已废弃
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

108 lines
2.8 KiB

import {DropImageFetchError} from "./errors.js";
import {eventOn} from "callforth";
const adaptOldFormat = detectedCodes => {
if (detectedCodes.length > 0) {
const [firstCode] = detectedCodes;
const [
topLeftCorner,
topRightCorner,
bottomRightCorner,
bottomLeftCorner
] = firstCode.cornerPoints
return {
content: firstCode.rawValue,
location: {
topLeftCorner,
topRightCorner,
bottomRightCorner,
bottomLeftCorner,
// not supported by native API:
topLeftFinderPattern: {},
topRightFinderPattern: {},
bottomLeftFinderPattern: {}
},
imageData: null
}
} else {
return {
content: null,
location: null,
imageData: null
}
}
}
/**
* Continuously extracts frames from camera stream and tries to read
* potentially pictured QR codes.
*/
export const keepScanning = (videoElement, options) => {
const barcodeDetector = new BarcodeDetector({formats: ["qr_code"]});
const {detectHandler, locateHandler, minDelay} = options;
const processFrame = state => async timeNow => {
if (videoElement.readyState > 1) {
const {lastScanned, contentBefore, locationBefore} = state
if (timeNow - lastScanned >= minDelay) {
const detectedCodes = await barcodeDetector.detect(videoElement);
const {content, location, imageData} = adaptOldFormat(detectedCodes)
if (content !== null && content !== contentBefore) {
detectHandler({content, location, imageData});
}
if (location !== null || locationBefore !== null) {
locateHandler(detectedCodes);
}
window.requestAnimationFrame(processFrame({
lastScanned: timeNow,
contentBefore: content ?? contentBefore,
locationBefore: location
}))
} else {
window.requestAnimationFrame(processFrame(state))
}
}
};
processFrame({
contentBefore: null,
locationBefore: null,
lastScanned: performance.now()
})();
};
const imageElementFromUrl = async url => {
if (url.startsWith("http") && url.includes(location.host) === false) {
throw new DropImageFetchError();
}
const image = document.createElement("img");
image.src = url;
await eventOn(image, "load");
return image;
}
export const processFile = async file => {
const barcodeDetector = new BarcodeDetector({formats: ["qr_code"]})
const detectedCodes = await barcodeDetector.detect(file)
return adaptOldFormat(detectedCodes)
}
export const processUrl = async url => {
const barcodeDetector = new BarcodeDetector({formats: ["qr_code"]})
const image = await imageElementFromUrl(url);
const detectedCodes = await barcodeDetector.detect(image)
return adaptOldFormat(detectedCodes)
}