如何在不刷新闪烁的情况下在浏览器中显示不断变化的图像文件?

Posted

技术标签:

【中文标题】如何在不刷新闪烁的情况下在浏览器中显示不断变化的图像文件?【英文标题】:How to display a constantly changing image file in a browser without refresh flicker? 【发布时间】:2011-07-23 06:08:49 【问题描述】:

我正在使用 html 在浏览器上显示图像(来自文件)...我有另一个程序不断截取我的屏幕截图并将其存储为图像文件“image.jpeg”。我定期使用 setTimeout 在浏览器上显示此图像。但是图像在浏览器上没有改变..

这是我的代码...我使用了一个 Image 对象,以便每次运行 javascript 函数时都会加载一个新图像,但这似乎不起作用...

<html>

<head>

<script type="text/JavaScript">

var x=0, y=0;
var canvas, context, img;

function timedRefresh(timeoutPeriod)

    canvas = document.getElementById("x");
    context = canvas.getContext("2d");
    img = new Image();
    img.src = "image.jpeg";
    context.drawImage(img, x, y);
    x+=20; y+=20;
    //img.destroy();
    setTimeout("timedRefresh(1000)",timeoutPeriod);


</script>

<title>JavaScript Refresh Example</title>

</head>

<body onload="JavaScript:timedRefresh(1000);">

<canvas id="x"   />

</body>
</html>

【问题讨论】:

【参考方案1】:

首先,当您设置图像对象的src 属性时,图像尚未加载,当图像的onload 被触发时(图像完成加载时),您需要刷新画布.

其次,浏览器尝试使用缓存的图像image.jpeg。为避免这种情况,请向图像 URI 添加虚假参数。

例如:

var timeoutPeriod = 1000;
var imageURI = 'image.jpeg';
var x=0, y=0;
var img = new Image();
img.onload = function() 
    var canvas = document.getElementById("x");
    var context = canvas.getContext("2d");

    context.drawImage(img, x, y);
    x+=20; y+=20;
    setTimeout(timedRefresh,timeoutPeriod);
;

function timedRefresh() 
    // just change src attribute, will always trigger the onload callback
    img.src = imageURI + '?d=' + Date.now();

然后它应该可以工作了。

【讨论】:

使用虚假属性来防止使用缓存图像是个好主意。【参考方案2】:

这是一个完整的工作示例。只需配置urlrefeshInterval。它使用Yannick 的缓存预防,并且不会按照Piotr 的建议在每次重新加载时重新创建img 对象。

<html>
<head>
<script type="text/JavaScript">
var url = "cam1.php"; //url to load image from
var refreshInterval = 1000; //in ms
var drawDate = true; //draw date string
var img;

function init() 
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    img = new Image();
    img.onload = function() 
        canvas.setAttribute("width", img.width)
        canvas.setAttribute("height", img.height)
        context.drawImage(this, 0, 0);
        if(drawDate) 
            var now = new Date();
            var text = now.toLocaleDateString() + " " + now.toLocaleTimeString();
            var maxWidth = 100;
            var x = img.width-10-maxWidth;
            var y = img.height-10;
            context.strokeStyle = 'black';
            context.lineWidth = 2;
            context.strokeText(text, x, y, maxWidth);
            context.fillStyle = 'white';
            context.fillText(text, x, y, maxWidth);
        
    ;
    refresh();

function refresh()

    img.src = url + "?t=" + new Date().getTime();
    setTimeout("refresh()",refreshInterval);


</script>
<title>JavaScript Refresh Example</title>
</head>

<body onload="JavaScript:init();">
<canvas id="canvas"/>
</body>
</html>

【讨论】:

使用画布元素真的可以减少闪烁!【参考方案3】:

我认为您不需要每次都在 timedRefresh() 中创建 Image 对象。只需创建一个实例并不断更改其src 属性。对于您的代码 sn-p,img 必须是全局变量。

不过,主要问题是您仍然会在 Opera 中看到闪烁(但类型不同)。见:Image source update in JavaScript with Opera

【讨论】:

以上是关于如何在不刷新闪烁的情况下在浏览器中显示不断变化的图像文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不通过 HTTP 加载图像的情况下在 HTML 中显示“重新加载”符号?

如何在不使用 ajax 刷新的情况下在我的页面上显示我的 php 响应?

如何在不刷新html页面的情况下在表格上显示数据(使用nodejs和mysql ajax)

如何在不刷新页面的情况下在 ReactJS 中重新加载?

使用 jQuery-AJAX 向 PHP 提交表单并在不刷新的情况下在 div 中显示新内容的问题

Vuex:在不编写 itvuex 的情况下在页面刷新时保持状态?