【问题标题】:Matching canvas resolution with the video resolution - superimposition将画布分辨率与视频分辨率匹配 - 叠加
【发布时间】:2016-06-08 23:57:14
【问题描述】:

我在 div 中定义了一个画布和一个视频:

<div id="videos">
    <canvas id="my-canvas"></canvas>
    <video id="remote-video" autoplay></video>
</div>

这是css:

#my-canvas {
    display: block;
    height: 100%;
    max-height: 100%;
    max-width: 100%;
    object-fit: cover;
    /* no letterboxing */
    opacity: 1;
    z-index: 2;
    position: absolute;
    -moz-transform: rotateY(180deg);
    -ms-transform: rotateY(180deg);
    -o-transform: rotateY(180deg);
    -webkit-transform: rotateY(180deg);
    transform: rotateY(180deg);
    transition: opacity 1s;
    width: 100%;
}

#remote-video {
    display: block;
    height: 100%;
    max-height: 100%;
    max-width: 100%;
    object-fit: cover;
    /* no letterboxing */
    opacity: 0;
    -moz-transform: rotateY(180deg);
    -ms-transform: rotateY(180deg);
    -o-transform: rotateY(180deg);
    -webkit-transform: rotateY(180deg);
    transform: rotateY(180deg);
    transition: opacity 1s;
    width: 100%;
}

当我绘制画布时,分辨率似乎与视频的分辨率不匹配。这是javascript代码:

var my_canvas = (function() {

var options;
var video;
var canvas;
var context;
var renderTimer;

function initVideoStream() {
    if (options.videoElement) {
        video = document.getElementById(options.videoElement);
        video.setAttribute('width', options.width);
        video.setAttribute('height', options.height);

        initCanvas();
    } else {
        options.onNotSupported();
    }
}

function initCanvas() {
    canvas = document.createElement("canvas");
    canvas.setAttribute('width', options.width);
    canvas.setAttribute('height', options.height);

    context = canvas.getContext('2d');

    startCapture();
}

function startCapture() {
    renderTimer = setInterval(function() {
        try {
            context.drawImage(video, 0, 0, video.width, video.height);
            options.onFrame(canvas);
        } catch (e) {
            // TODO
        }
    }, Math.round(1000 / options.fps));
}

function stopCapture() {
    if (renderTimer) {
        clearInterval(renderTimer);
    }

    options.onClear();
}

return {
    init: function(captureOptions) {
        var doNothing = function(){};

        options = captureOptions || {};

        options.fps = options.fps || 30;
        options.width = options.width || 640;
        options.height = options.height || 480;
        options.videoElement = options.videoElement || null;

        options.onSuccess = options.onSuccess || doNothing;
        options.onError = options.onError || doNothing;
        options.onNotSupported = options.onNotSupported || doNothing;
        options.onFrame = options.onFrame || doNothing;
        options.onClear = options.onClear || doNothing;

        initVideoStream();
    },

    start: startCapture,

    stop: stopCapture
};
})();

注意:

1) options.videoElement = document.getElementById('my-canvas');

2) 我使用了 options.width 和 height 的不同值。它没有修复。

如何将画布完全叠加在视频上?

【问题讨论】:

    标签: javascript html video canvas resolution


    【解决方案1】:

    这个调整大小的代码解决了这个问题:

        function startCapture() {
            window.requestAnimFrame = (function() {
                return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( /* function */ callback, /* DOMElement */ element) {
                    window.setTimeout(callback, 1000 / options.fps);
                };
            })();
    
            animate();
        }
    
        function stopCapture() {
            requestAnimFrame = null;
            options.onClear();
        }
    
        function animate() {
            if (requestAnimFrame != null) {
                requestAnimFrame(animate);
                render();
            }
        }
    
        function render() {
            try {
                var video_width = video.offsetWidth;
                var video_height = video.offsetHeight;
                var ratio = video_width / video_height;
                var target_width;
                var target_height;
                var y_of_video = 0;
                var x_of_video = 0
                if (video_width > video_height) {
                    target_width = canvas.width;
                    target_height = canvas.width / ratio;
                    y_of_video = (canvas.height - target_height) / 2;
                } else {
                    target_width = canvas.height;
                    target_height = canvas.height * ratio;
                    x_of_video = (canvas.width - target_width) / 2;
                }
                context.drawImage(video, x_of_video, y_of_video, target_width, target_height);
                options.onFrame(canvas);
            } catch (e) {
                console.log("Failed to render canvas");
            }
        }
    

    注意:答案根据 350D 的建议编辑。

    【讨论】:

    • 我建议使用 requestAnimationFrame 而不是 setInterval 来防止任何 vsinc 问题、性能问题和更高的电源效率
    • 感谢您的建议,您能举个例子吗?我不是 html5 专家!
    • function startCapture() { var ... function render() { render routine ... window.requestAnimationFrame(render); } 使成为(); }
    • 您应该在渲染例程之后调用render() 以确保一切都已完成。所以,只需在options.onFrame(canvas); 之后调用window.requestAnimationFrame(render);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 2013-08-20
    • 2018-07-12
    • 2022-01-27
    • 2018-01-18
    • 2017-08-23
    • 1970-01-01
    相关资源
    最近更新 更多