ColonelParrot/jscanify

IOS Compatibility

warisab opened this issue · 27 comments

Camer freeze in IOS browsers
any solution please?

Can you attach the code you used?





Capture Image

const scanner = new jscanify();
const canvas = document.getElementById("canvas");
const result = document.getElementById("result");
const canvasCtx = canvas.getContext("2d");
const capturedImage = document.getElementById("capturedImage");
// const imageResult = result.getContext("2d");
let videoStream = null;
var resultCanvas = null;

async function startCamera() {
    try {
        const devices = await navigator.mediaDevices.enumerateDevices();
        const videoDevices = devices.filter((device) => device.kind === "videoinput");

        if (videoDevices.length > 0) {
            const videoConstraints = {
                video: {
                    facingMode: "environment",
                    width: { ideal: 800 },
                    height: { ideal: 600 }
                },
                audio: false
            };

            videoStream = await navigator.mediaDevices.getUserMedia(videoConstraints);
            const video = document.createElement("video");
            video.srcObject = videoStream;

            video.onloadedmetadata = () => {
                video.play();

                // Set canvas size to match the screen dimensions
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;

                const renderInterval = 100; // Set a frame rate (approximately 30 fps)

                let lastRenderTime = 0;
                const renderFrame = (currentTime) => {
                    if (currentTime - lastRenderTime >= renderInterval) {
                        canvasCtx.drawImage(video, 0, 0, canvas.width, canvas.height);

                        const options = {
                            color:"blue",
                            thickness: 5
                        }
                        // Highlight the paper and draw it on the same canvas
                        resultCanvas = scanner.highlightPaper(canvas, options);
                        canvasCtx.clearRect(0, 0, canvas.width, canvas.height);
                        canvasCtx.drawImage(resultCanvas, 0, 0, canvas.width, canvas.height);

                        lastRenderTime = currentTime;
                    }

                    requestAnimationFrame(renderFrame);
                };

                requestAnimationFrame(renderFrame);

                document.getElementById("captureButton").addEventListener("click", () => {
                    if (videoStream) {
                        const paperWidth = 500;
                        const paperHeight = 1000;
                        const image = new Image();
                        image.src = resultCanvas.toDataURL("image/png");

                        image.onload = function () {
                            const resultCanvas = scanner.extractPaper(image, paperWidth, paperHeight);
                            // imageResult.drawImage(resultCanvas, 0, 0);
                            // document.body.appendChild(resultCanvas);
                            capturedImage.style.outline = "none";
                            capturedImage.style.display = "block";
                            capturedImage.src = resultCanvas.toDataURL("image/png");

                            // Add a download button
                            const downloadButton = document.createElement("a");
                            downloadButton.href = resultCanvas.toDataURL("image/png");

                            downloadButton.download = "captured_image.png";
                            downloadButton.textContent = "Download Image";

                            // Append the download button to the DOM
                            document.body.appendChild(downloadButton);

                            // Trigger a click event on the download button to initiate the download
                            downloadButton.click();
                        };
                    }
                });
            };
        } else {
            alert("No video input devices found.");
        }
    } catch (error) {
        console.error("Error accessing camera:", error);
    }
}

startCamera();

I also tried to copy paste the extact code from documentation it still get freeze

Can you attach the code you used?

Hello sir are you available?

I'm taking a look right now

I'm taking a look right now

Thank you so much

Can you send your HTML too?

Can you send your HTML too?

<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>





Capture Image

<style> /* Style the capture button as a circle */ .capture-button { width: 100px; height: 100px; background-color: #0074D9; /* Change to your preferred button color */ border-radius: 50%; position: absolute; bottom: 20px; left: calc(50% - 50px); display: flex; justify-content: center; align-items: center; color: #fff; font-weight: bold; cursor: pointer; } </style>

Is that all the HTML? You are using canvases in your code.

Is that all the HTML? You are using canvases in your code.

yes, im just doing testing

I think I'm missing some HTML here. Can you include the full HTML? For instance, I'm missing a #captureButton.

ok sure

<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> <style> /* Style the capture button as a circle */ .capture-button { width: 100px; height: 100px; background-color: #0074D9; /* Change to your preferred button color */ border-radius: 50%; position: absolute; bottom: 20px; left: calc(50% - 50px); display: flex; justify-content: center; align-items: center; color: #fff; font-weight: bold; cursor: pointer; } </style>

Capture Image

<script> const scanner = new jscanify(); const canvas = document.getElementById("canvas"); const result = document.getElementById("result"); const canvasCtx = canvas.getContext("2d"); const capturedImage = document.getElementById("capturedImage"); // const imageResult = result.getContext("2d"); let videoStream = null; var resultCanvas = null; async function startCamera() { try { const devices = await navigator.mediaDevices.enumerateDevices(); const videoDevices = devices.filter((device) => device.kind === "videoinput"); if (videoDevices.length > 0) { const videoConstraints = { video: { facingMode: "environment", width: {ideal: 800}, height: {ideal: 600} }, audio: false }; videoStream = await navigator.mediaDevices.getUserMedia(videoConstraints); const video = document.createElement("video"); video.srcObject = videoStream; video.onloadedmetadata = () => { video.play(); // Set canvas size to match the screen dimensions canvas.width = window.innerWidth; canvas.height = window.innerHeight; const renderInterval = 100; // Set a frame rate (approximately 30 fps) let lastRenderTime = 0; const renderFrame = (currentTime) => { if (currentTime - lastRenderTime >= renderInterval) { canvasCtx.drawImage(video, 0, 0, canvas.width, canvas.height); const options = { color: "blue", thickness: 5 } // Highlight the paper and draw it on the same canvas resultCanvas = scanner.highlightPaper(canvas, options); canvasCtx.clearRect(0, 0, canvas.width, canvas.height); canvasCtx.drawImage(resultCanvas, 0, 0, canvas.width, canvas.height); lastRenderTime = currentTime; } requestAnimationFrame(renderFrame); }; requestAnimationFrame(renderFrame); document.getElementById("captureButton").addEventListener("click", () => { if (videoStream) { const paperWidth = 500; const paperHeight = 1000; const image = new Image(); image.src = resultCanvas.toDataURL("image/png"); image.onload = function () { const resultCanvas = scanner.extractPaper(image, paperWidth, paperHeight); // imageResult.drawImage(resultCanvas, 0, 0); // document.body.appendChild(resultCanvas); capturedImage.style.outline = "none"; capturedImage.style.display = "block"; capturedImage.src = resultCanvas.toDataURL("image/png"); // Add a download button const downloadButton = document.createElement("a"); downloadButton.href = resultCanvas.toDataURL("image/png"); downloadButton.download = "captured_image.png"; downloadButton.textContent = "Download Image"; // Append the download button to the DOM document.body.appendChild(downloadButton); // Trigger a click event on the download button to initiate the download downloadButton.click(); }; } }); }; } else { alert("No video input devices found."); } } catch (error) { console.error("Error accessing camera:", error); } } startCamera(); </script>

I tested out the code and it appears to be OK. What behavior are you observing on iOS? Is it reading from the camera properly? When does the freezing happen

I don't know whenever i opened the page camera stuck
works well in android

OK so it freezes immediately when you open the page on iOS?

Yes

Uploading Skype_Picture_2023_11_02T23_29_45_273Z.jpeg…

Check if this fixes your issue opencv/opencv#15707

ok I'll try this and let you know tomorrow

can you tell me how to highlightpaper on video tag you are using it on canvas

Hello sir have you checked that?

You can directly write a video to a canvas with drawImage.

const video = document.querySelector('video')
const canvas = document.querySelector('canvas')
canvas.getContext('2d').drawImage(video, 0, 0)

sir can you tell me how to get the size of highliter box I want to download exact size of picture of highlited box

const resultCanvas = scanner.highlightPaper(overlayCanvas, options);
// test = resultCanvas;
overlayCtx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height); // Clear the overlay canvas
overlayCtx.drawImage(resultCanvas, 0, 0); // Draw the highlighted paper on the overlay canvas

the captured picture is too blury

Hi @warisab the jscanify.highlightPaper() method returns a canvas element containing the image.

If you are still having an issue, please let me know and I'll reopen this ticket.