I want to refresh an image every 1 second. This picture is dynamically generated by my webcam, but this script sometimes display broken images when browser didnt yet load a picture before display. How to detect when picture is loaded and then change the diplay picture?
I have a code like this:
<img id="image" src="webcam.jpg">
<script>
setInterval(function() {
var myImageElement = document.getElementById('image');
myImageElement.src = 'webcam.jpg?rand=' + Math.random();
}, 1000);
</script>
You should wait for the image to be loaded first, before replacing it.
For this, you can use different approaches. What I usually do, is to create another image which is not visible and replace the one visible once the previous image is loaded.
Your code should look like this if you want to follow this approach:
<img id="image" src="webcam.jpg">
<script>
setInterval(function() {
var url = 'webcam.jpg?rand=' + Math.random();
var img = new Image();
img.src = url;
img.addEventListener('load', function() {
var myImageElement = document.getElementById('image');
myImageElement.src = url;
});
}, 1000);
</script>
What you can also do is play with css styles to make the image hidden or visible depending on the state, but that would make your image appear and disappear which is a bit ugly...
I hope it helps :)
I think you can use something like this:
var _img = document.getElementById('pic'),
urlToImage = 'pic.jpg',
modified = false, lastModified = 0;
setInterval(function(){
fetch(urlToImage)
.then(function(resp){
var f = new File([resp],"file");
switch(true) {
case modified === false:
lastModified = f.lastModified;
modified = true; break;
default:
modified = false;
if(lastModified < f.lastModified) {
modified = true;
}
}
return resp.blob();
})
.then(function(blobdata){
switch(true) {
case modified === true:
var obj_url = URL.createObjectURL(blobdata);
_img.src = obj_url;
break;
}
});
},1000);
<img src="" id="pic" alt="LOCAL pic here"/>
I think that looking at lastModified time in File properties is a good way to assume image was finished written on the server.
Hope this helps.
Try using this after loading the document
$( document ).ready(function() {
setInterval(function() {
var myImageElement = document.getElementById('image');
myImageElement.src = 'webcam.jpg?rand=' + Math.random();
}, 500);
});
Hope this helps
Related
Please answer this question, as I am struggling a lot with it.
I am trying to change image source on mouse over. I am able to do it, but image is not displaying on page.
I am trying to change image source to cross domain URL. I can see that in DOM image source is changing but on page its not.
I have tried all solutions mentioned in LINK, but none of them is working.
Please let me solution to problem.
NOTE:
I can see in network tab image is taking some time to download (about 1 sec).
It is an intermediate issue, sometime image is loading and sometimes its not
CODE:
document.getElementsByTagName('img')[0].addEventListener('mouseover', function()
{
document.getElementsByTagName('img')[0].setAttribute('src', 'url/of/the/image');
});
have you tried loading images before everything else?
function initImages(){
var imC = 0;
var imN = 0;
for ( var i in Images ) imN++;
for(var i in Images){
var t=Images[i];
Images[i]=new Image();
Images[i].src=t;
Images[i].onload = function (){
imC++;
if(imC == imN){
console.log("Load Completed");
preloaded = 1;
}
}
}
}
and
var Images = {
one image: "path/to/1.png",
....
}
then
if( preloaded == 1 ){
start_your_page();
}
Here the code that will remove the img tag and replace it with a new one:
document.getElementsByTagName('img')[0].addEventListener('mouseover', function() {
var parent = document.getElementsByTagName('img')[0].parentElement;
parent.removeChild(document.getElementsByTagName('img')[0]);
var new_img = document.createElement("img");
new_img.src = "https://upload.wikimedia.org/wikipedia/commons/6/69/600x400_kastra.jpg";
parent.appendChild(new_img);
});
<img src="https://www.w3schools.com/w3images/fjords.jpg">
I resolved the issue using code:
function displayImage() {
let image = new image();
image.src="source/of/image/returned/from/service";
image.addEventListener('load', function () {
document.getElementsByTagName('img')[0].src = image.src;
},false);
}
Here in code, I am attaching load event to image, source of image will be changed after image is loaded.
I am refreshing images from webcams every second on an app. The problem I have is if for a few seconds an image is not retrieved from the camera (which happens frequently) I end up with a broken image. I would like to have it so that it only refreshes if and when a new image is found.
So far I have
var int_time = setInterval(function() {
var myImageElement = document.getElementById('myImage');
myImageElement.src = '<%= EVERCAM_API %>cameras/<%= #camera["id"] %>/snapshot.jpg?api_id=<%= current_user.api_id %>&api_key=<%= current_user.api_key %>&rand=' + new Date().getTime();
}, 1000);
Is it possible to stop the refresh if the image not retrieved?
Following snippet will help.
Solution:
1) Create a dynamic image object
2) Bind onload event
3) set src of dynamically created image object to the desired new image link
4) on success of loading dynamic image, replace original tag or set the src of original image tag to the latest image link
This will avoid problem of broken image
Code:
var int_time;
(function(){
var el = document.getElementById('myImage');
function loadImage () {
var img = new Image()
, src = '<%= EVERCAM_API %>cameras/<%= #camera["id"] %>/snapshot.jpg?api_id=<%= current_user.api_id %>&api_key=<%= current_user.api_key %>&rand=' + new Date().getTime();;
img.onload = function() {
if (!! el.parent)
el.parent.replaceChild(img, el)
else
el.src = src;
}
img.src = src;
}
int_time = setInterval(loadImage, 1000);
}());
Save it in a variable and then check the variable for its contents, but I cannot tell you what the api returns if the image could not be fetched. You need to fix that on your own I assume false here...
var int_time = setInterval(function() {
var myImageElement = document.getElementById('myImage');
var newImage = '<%= EVERCAM_API %>cameras/<%= #camera["id"] %>/snapshot.jpg?api_id=<%= current_user.api_id %>&api_key=<%= current_user.api_key %>&rand=' + new Date().getTime();
if(newImage != false) { //Here you have to build an expression if the image is valid
myImageElement.src = newImage;
}
}, 1000);
I've got a question in regards to javascript and dynamically displaying images to
form an animation.
The pictures I have are around 1360x768 in size and quite big despite being .png pics.
I've come up with a code for switching out the pics dynamically, but even run on a local
webserver it is too slow (thus sometimes I see the pic being built).
So my question is: is there a better way to do this than dynamically switching out
the "src" part of the image tag, or is there something else that could be done in combination with that, to make sure that the user doesn't have any strange phenomenons
on the client?
<script>
var title_index = 0;
function display_title()
{
document.getElementById('picture').src=
"pics/title_" + title_index + '.png';
if (title_index < 100) {
title_index = title_index + 5;
setTimeout(display_title,3000);
}
}
</script>
<body onload="setTimeout(display_image,3000)">
<image id="picture" src="pic/title_0.png"/>
</body>
Thanks.
I've had this problem too, even when preloading the images into the cache,
Google's The Hobbit experiment does something interesting. They do low resolution while animating and switch it for a hiresolution if you "pause" (stop scolling in the case of The Hobbit experiment). They also use the HTML5 canvas tag to smooth out the animation.
Here's their blog post about their method:
http://www.html5rocks.com/en/tutorials/casestudies/hobbit-front-end/
Their end product:
http://middle-earth.thehobbit.com
Edit:
Pre loading example:
<!Doctype html>
<head>
<title>test</title>
</head>
<body>
<canvas id="myCanvas" width="1360" height="768"></canvas>
<script type="text/javascript">
var images = {};
var loadedImages = 0;
var numImages = 0;
var context = '';
function loadImages(sources, callback)
{
// get num of sources
for(var src in sources)
{
numImages++;
}
for(var src in sources)
{
images[src] = new Image();
images[src].onload = function()
{
if(++loadedImages >= numImages)
{
callback(images);
}
};
images[src].src = sources[src];
}
}
var canvas = document.getElementById('myCanvas');
context = canvas.getContext('2d');
var sources =
{
frame0: 'http://piggyandmoo.com/0001.png',
frame1: 'http://piggyandmoo.com/0002.png',
frame2: 'http://piggyandmoo.com/0003.png',
frame3: 'http://piggyandmoo.com/0004.png',
frame4: 'http://piggyandmoo.com/0005.png',
frame5: 'http://piggyandmoo.com/0006.png',
frame5: 'http://piggyandmoo.com/0007.png',
frame5: 'http://piggyandmoo.com/0008.png',
frame5: 'http://piggyandmoo.com/0009.png'
};
var width = 1360;
var height = 768;
var inter = '';
var i = 0;
function next_frame()
{
if(numImages > i)
{
context.drawImage(images['frame' + (i++)], 0, 0);
}
else
{
clearInterval(inter);
}
}
loadImages(sources, function(images)
{
//animate using set_timeout or some such...
inter = setInterval(function()
{
next_frame();
}, 1000);
});
</script>
</body>
Code modified from: www.html5canvastutorials.com/tutorials/html5-canvas-image-loader/
You could overcome this issue by preloading the images on page load. This means that the images would then be stored in memory and immediately available to you. Take a look at the following:
JavaScript Preloading Images
http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
Im sure this has got to be something simple that I am overlooking, but I can't seem to get my canvas to display an jpg stored on the server.
<img id="test_img" alt="test" src="/media/tmp/a4c1117e-c310-4b39-98cc-43e1feb64216.jpg"/>
<canvas id="user_photo" style="position:relative;"></canvas>
<script type="text/javascript">
var image = new Image();
image.src = "/media/tmp/a4c1117e-c310-4b39-98cc-43e1feb64216.jpg";
var pic = document.getElementById("user_photo");
pic.getContext('2d').drawImage(image, 0, 0);
</script>
the <img> displays as expected, however the canvas is blank, though it does seem to have the correct dimensions. Any one see what I'm doing wrong?
My tired eyes will appreciate any help.
Thanks
you may want to use the following approach
image.onload = function() {
pic.getContext('2d').drawImage(image, 0,0);
}
so you ensure that the image is loaded when trying to draw it.
var initialFloorplanWidth = 0;
var initialFloorplanHeight = 0;
var canvasImage = new Image();
documentReady = function () {
preloadFloorplan();
}
preloadFloorplan = function () {
onLoad = function () {
initialFloorplanHeight = canvasImage.height;
initialFloorplanWidth = canvasImage.width;
var canvasHtml = '<canvas id="MainCanvas" width="' + initialFloorplanWidth + '" height="' + initialFloorplanHeight + '">Canevas non supportés</canvas>';
$("#MainContainer").append(canvasHtml);
var canvas = $("#MainCanvas")[0];
var canvasContext = canvas.getContext("2d");
canvasContext.drawImage(canvasImage, 0, 0);
}
canvasImage.onload = onLoad;
canvasImage.src = initialFloorplan;
}
This code works well.
Try doing that when the document is loaded. I have a feeling your code is running before the image is available. You can also detect when the img itself is loaded. See this.
Maybe it's something to do with the rest of your code. Is "user_photo" identified in the code?
This code is meant for a real estate website I am updating for my company. Basically, There is a table with the property name, address, etc, and an image. Originally, I was coding this website in ASP.net switch over to regular Javascript for a few reasons (hosting overhead etc).
Sections of this code are from a few different tutorials out there, one of which is an ASP.net modal div image "enlarger" tutorial, which is sort of the basis combined with a few other sites. I have yet to comment in their names etc, but I plan on giving them credit in the code. Thier links are below before I post my code.
http://archive.aspsnippets.com/post/2009/07/06/Image-Gallery-using-ASPNet-GridView-control.aspx
My code is essentially as follows (I will trim the fat and excess line breaks in the style section):
First are the modal style tags from that tutorial by Mudassar Khan (partially relevant):
<style>
body {margin:0;padding:0;height:100%;}
.modal {display: none;position: absolute;top: 0px;left: 0px;background-color:black;z-index:100;opacity: 0.8; filter: alpha(opacity=60);-moz-opacity:0.8;min-height: 100%;}
&#divImage{display: none;z-index: 1000;position: fixed;top: 0;left: 0;background-color:White;height: 550px;width: 600px;padding: 3px;border: solid 1px black;}
<style>
Then comes his script, which I may have tweaked here and there:
<script type="text/javascript">
function LoadDiv(url) {
var img = new Image();
var bcgDiv = document.getElementById("divBackground");
var imgDiv = document.getElementById("divImage");
var imgFull = document.getElementById("imgFull");
var imgLoader = document.getElementById("imgLoader");
img.src = url;
var tcopy = img.src.slice(0,(img.src.length-4)) + "_big.png";
img.src = tcopy;
img.onload = function () {
imgFull.src = tcopy
imgFull.style.display = "block";
imgLoader.style.display = "none";
};
var width = document.body.clientWidth;
if (document.body.clientHeight > document.body.scrollHeight) {
bcgDiv.style.height = document.body.clientHeight + "px";
}
else {
bcgDiv.style.height = document.body.scrollHeight + "px";
}
imgDiv.style.left = (width - 650) / 2 + "px";
imgDiv.style.top = "20px";
bcgDiv.style.width = "100%";
bcgDiv.style.display = "block";
imgDiv.style.display = "block";
return false;
}
function HideDiv() {
var bcgDiv = document.getElementById("divBackground");
var imgDiv = document.getElementById("divImage");
var imgFull = document.getElementById("imgFull");
imgLoader.style.display = "block"; // I added as it seems to bring back the loader gif
if (bcgDiv != null) {
bcgDiv.style.display = "none";
imgDiv.style.display = "none";
imgFull.style.display = "none";
}
}
</script>
Now All this above script gets called upon a onClick Event Handler on an image of each of the real estate companies properties. This will work well to both preload images with the little animated gif and the close button works fine. It works on more than one image, BUT if the image is already preloaded, I cant think of a way to force the redisplay of an already preloaded image if a user clicks on the photo, then clicks close to hide the div tag and then clicks on the same preloaded image.
That event handler looks like this:
img onClick="return LoadDiv(this.src);" src="http://www.ourcompany.com/images/prop_thumbs/Some_plaza.png" style="min-width:200 px;max-height:150 px;max-width:200 px;"
I thought global booleans would work, but then I realized, theres no telling which and what is preloaded, so the boolean might not help if you can't pass something meaningful back and forth.
I'm not asking any one to do my work for me, however I would appreciate suggestions in the right direction.
Regards and TIA!
You could make a array of all of the images with key values of loaded. For instance.
image_list = {image1:false,image2:true,image3:false};
true and false being loaded or not loaded. When an image is clicked just update the array.
image_list[image1] = true;
Did this really quick, so my syntax might be off, feel free to correct me or berate me...
Yay!!! Figured it out with the help of both jhanifen and the guy who did the tutorial I used (he actually emailed me). My code is below (its an excerpt, but you'll get the idea):
images = new Array(30);
//need to define each image to be in array
images[0]="website/images/prop_thumbs/property1_big.png";
images[1]="website/images/prop_thumbs/property2_big.png";
images[2]="website/images/prop_thumbs/property3_big.png";
//This continues for some time
imagesLoaded = new Array(30);
// per stack overflow person suggestion make array of bool values; initialize them all to false on page load
function onLoadScript() {
for (i = 0; i < imagesLoaded.length; ++ i)
{
imagesLoaded [i] = false;
}
}
// the above is called onLoad in body tag
// Changes the script for Loading the Div tag are below:
function LoadDiv(imgNum) {
var img = new Image();
var bcgDiv = document.getElementById("divBackground");
var imgDiv = document.getElementById("divImage");
var imgFull = document.getElementById("imgFull");
var imgLoader = document.getElementById("imgLoader");
img.src = images[imgNum];
if(imagesLoaded[imgNum] = true)
{ // this statement triggers same as onload below!
imgFull.src = img.src
imgFull.style.display = "block";
imgLoader.style.display = "none";
}
img.onload = function () {
imgFull.src = img.src
imgFull.style.display = "block";
imgLoader.style.display = "none";
imagesLoaded[imgNum] = true;
};
The rest of the document is the same except I changed the onClick event handler for the property images to LoadDiv(and some sequential number);
Thanks to all for your help! Particular props to both Mudassar Khan and jhanifen!