I create a project to scan a barcode, but on mobil or webCam the frame is too big. I want crop it. I read lot of thing about, apparently already implemented function... but I don't
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@("@")quasar/extras/material-icons/material-icons.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/ionicons@("@")4.0.0/dist/css/ionicons.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/animate.css@("@")3.5.2/animate.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/quasar.min.css" />
<script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/quasar.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/icon-set/ionicons-v4.umd.prod.js"></script>
<script type="text/javascript" src="https://unpkg.com/@("@")zxing/library@latest/umd/index.min.js"></script>
</head>
<body>
<script>
function cropping(canvas) {
const cameraCanvasImageWidth = canvas.width;
const cameraCanvasImageHeight = canvas.height;
const videoElementHeight = (document.querySelector('zxing-scanner video')).offsetHeight;
const videoElementWidth = (document.querySelector('zxing-scanner video')).offsetWidth;
let factor = 1;
if (videoElementWidth > videoElementHeight) {
factor = cameraCanvasImageWidth / videoElementWidth;
} else {
factor = cameraCanvasImageHeight / videoElementHeight;
}
const width = Math.floor((this.squareShape ? 250 : 450) * factor);
const height = Math.floor((this.squareShape ? 250 : 200) * factor);
const left = (cameraCanvasImageWidth - width) / 2;
const top = (cameraCanvasImageHeight - height) / 2;
const croppedCanvas = document.createElement('canvas');
croppedCanvas.width = width;
croppedCanvas.height = height;
const croppedCanvasContext = croppedCanvas.getContext('2d');
croppedCanvasContext.rect(0, 0, width, height);
croppedCanvasContext.fillStyle = 'white';
croppedCanvasContext.fill();
croppedCanvasContext.drawImage(canvas, left, top, width, height, 0, 0, width, height);
// These lines can be used to show the cropped part of the image stream that is used
// to find the code and check if the highlighted area matches the cropped image
document.getElementById('croppedSvg').innerHTML = '';
const span = document.createElement('span');
span.textContent = `${cameraCanvasImageWidth} x ${cameraCanvasImageHeight} | ${videoElementWidth} x ${videoElementHeight}`;
span.style.position = 'absolute';
span.style.right = `0`;
span.style.color = 'white';
span.style.display = 'block';
document.getElementById('croppedSvg').appendChild(span);
croppedCanvas.style.marginTop = '20px';
croppedCanvas.style.transform = `scale(1)`;
croppedCanvas.style.transformOrigin = `right top`;
document.getElementById('croppedSvg').appendChild(croppedCanvas);
let luminanceSource = new HTMLCanvasElementLuminanceSource(croppedCanvas); // .invert() to support inverted codes
const hybridBinarizer = new HybridBinarizer(luminanceSource);
return new BinaryBitmap(hybridBinarizer);
};
var mixin = {
data: function () {
return {
selectedDeviceId: '', lstcams: [], result: '', codeReader: null
};
},
methods: {
openWebCam: function () {
const hints = new Map();
const enabledFormats = [
// ...ALL_FORMATS_WHICH_YOU_WANT_TO_ENABLE https://github.com/zxing-js/library/blob/master/src/core/BarcodeFormat.ts
ZXing.BarcodeFormat.CODE_39,ZXing.BarcodeFormat.EAN_13
];
hints.set(ZXing.DecodeHintType.POSSIBLE_FORMATS, enabledFormats);
this.codeReader = new ZXing.BrowserMultiFormatReader(hints);
//this.codeReader.createBinaryBitmapFromCanvas = cropping();
this.codeReader.listVideoInputDevices()
.then((videoInputDevices) => {
this.selectedDeviceId = videoInputDevices[0].deviceId;
if (videoInputDevices.length >= 1) { videoInputDevices.forEach((element) => { this.lstcams.push({ libelle: element.label, id: element.deviceId }); }); }
})
.catch((err) => {
//console.error(err)
});
this.codeReader.decodeFromVideoDevice(this.selectedDeviceId, 'video', (result, err) => {
if (result && this.result.indexOf(result.text) == -1) { this.result += result.text + "\n"; }
if (err && !(err instanceof ZXing.NotFoundException)) this.result = err;
});
},
CloseWebCam: function () { this.codeReader.reset(); this.result = ''; },
}
};
</script>
<div id="q-app">
<div>
<q-btn color="primary" flat label="Scanne" padding="xs" v-on:click="openWebCam()"></q-btn>
<q-btn color="secondary" flat label="Arrêt" padding="xs" v-on:click="CloseWebCam()"></q-btn>
</div>
<div class="row">
<div class="col-xs-12 col-md-6">
<video id="video" style="border: 1px solid gray; min-height: 100%; min-width: 100%; width: auto; height: auto; margin: 0; padding: 0;" willreadfrequently="true"></video>
</div>
</div>
<q-input class="col-xs-12 col-md-6" type="textarea" dense v-model="result" label="Résultat *">
<template v-if="result" v-slot:append tabindex="-1">
<q-icon name="cancel" v-on:click.stop="result = '' " class="cursor-pointer" />
</template>
</q-input>
</div>
<script>
const app = Vue.createApp({ mixins: [mixin] });
app.use(Quasar, {
framework: {
cssAddon: true,
plugins: ['Notify', 'LocalStorage', 'SessionStorage'],
config: {
notify: {
position: 'top-right',
timeout: 2500,
textColor: 'white',
actions: [{ icon: 'close', color: 'white' }]
}
}
}
});
app.mount('#q-app')
</script>
I see a crop function in zxing js file but don't know how to call it I read too this link but I don't see how to adpate it. Perhaps I take a bad way ??
Thanks for your help