Anyone have implemented real time document scanning using this library? #33
Answered
by
ColonelParrot
Antonio-Lucian-Popa
asked this question in
Q&A
-
|
I can't highlight the document on the device camera in realtime. I use vanilla js for this with the cdn, but didn't work. <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document Scanner cu Jscanify</title>
<style>
body {
margin: 0;
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
background: #111;
color: white;
}
#videoWrapper {
position: relative;
width: 100%;
max-width: 480px;
}
video,
canvas {
width: 100%;
height: auto;
border-radius: 8px;
}
#captureBtn {
margin: 20px;
padding: 10px 20px;
font-size: 18px;
border: none;
border-radius: 8px;
background: #09f;
color: white;
cursor: pointer;
}
#result {
margin-top: 20px;
}
</style>
</head>
<body>
<h2>Document Scanner</h2>
<video id="video" autoplay playsinline style="display: none;"></video>
<canvas id="sourceCanvas" style="display: none;"></canvas>
<canvas id="result"></canvas>
<button id="captureBtn">Capture document</button>
<script src="https://docs.opencv.org/4.7.0/opencv.js" async></script>
<script src="https://cdn.jsdelivr.net/gh/ColonelParrot/jscanify@master/src/jscanify.min.js"></script>
<script>
window.onload = function () {
initApp();
};
function initApp() {
const video = document.getElementById("video");
const canvas = document.getElementById("sourceCanvas");
const result = document.getElementById("result");
const captureBtn = document.getElementById("captureBtn");
const canvasCtx = canvas.getContext("2d");
const resultCtx = result.getContext("2d");
const scanner = new jscanify();
navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }).then((stream) => {
video.srcObject = stream;
video.onloadedmetadata = () => {
video.play();
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
result.width = video.videoWidth;
result.height = video.videoHeight;
setInterval(() => {
canvasCtx.drawImage(video, 0, 0, canvas.width, canvas.height);
let points = null;
const mat = cv.imread(canvas);
const contour = scanner.findPaperContour(mat);
if (contour) {
points = scanner.getCornerPoints(contour);
}
mat.delete();
resultCtx.clearRect(0, 0, result.width, result.height);
resultCtx.drawImage(canvas, 0, 0);
if (points) {
resultCtx.fillStyle = 'cyan';
resultCtx.strokeStyle = 'orange';
resultCtx.lineWidth = 4;
resultCtx.beginPath();
resultCtx.moveTo(points.topLeft.x, points.topLeft.y);
resultCtx.lineTo(points.topRight.x, points.topRight.y);
resultCtx.lineTo(points.bottomRight.x, points.bottomRight.y);
resultCtx.lineTo(points.bottomLeft.x, points.bottomLeft.y);
resultCtx.closePath();
resultCtx.stroke();
Object.values(points).forEach(p => {
resultCtx.beginPath();
resultCtx.arc(p.x, p.y, 6, 0, 2 * Math.PI);
resultCtx.fill();
});
}
}, 200);
};
});
captureBtn.addEventListener("click", () => {
const extracted = scanner.extractPaper(canvas, 600, 800);
document.body.appendChild(extracted);
});
}
</script>
</body>
</html> |
Beta Was this translation helpful? Give feedback.
Answered by
ColonelParrot
Apr 3, 2025
Replies: 1 comment 9 replies
-
|
{
topLeftCorner: { x: ..., y: ... },
topRightCorner: { x: ..., y: ... },
bottomLeftCorner: { x: ..., y: ... },
bottomRightCorner: { x: ..., y: ... },
}The issue arises here: resultCtx.beginPath();
resultCtx.moveTo(points.topLeft.x, points.topLeft.y);
resultCtx.lineTo(points.topRight.x, points.topRight.y);
resultCtx.lineTo(points.bottomRight.x, points.bottomRight.y);
resultCtx.lineTo(points.bottomLeft.x, points.bottomLeft.y);
resultCtx.closePath();
resultCtx.stroke();It should be |
Beta Was this translation helpful? Give feedback.
9 replies
Answer selected by
ColonelParrot
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment

getCornerPointsreturns an object in the following format:The issue arises here:
It should be
points.topLeftCorner.xinstead ofpoints.topLeft.x. You'll need to fix all occurrences of this issue.