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);
Related
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
This question already has answers here:
Get image dimensions with Javascript before image has fully loaded
(3 answers)
Closed 6 years ago.
I tried to get the actual size of images before they are displayed on HTML, and I do use this in most cases:
var imgae = new Image();
image.src = img.src;
image.onload = function() {
// Do something with image.width and image.height
// and insert an <img> into <body>
}
However when the image is too large so that it may take seconds to download, users have to wait until it completes before seeing the image. Is there any way where I can get the information before Image.onload is triggered (and of cause after the meta data of image is loaded), so that I can show part of it on the page?
If you are using jQuery and you are requesting image sizes you have to wait until they load or you will only get zeroes.
$(document).ready(function() {
$("img").load(function() {
alert($(this).height());
alert($(this).width());
});
});
If you are using jQuery 3.0 remember that load method was removed, use
$('img').on('load', function() {})
var _URL = window.URL || window.webkitURL;
function displayPreview(files) {
var file = files[0]
var img = new Image();
var sizeKB = file.size / 1024;
img.onload = function() {
$('#preview').append(img);
alert("Size: " + sizeKB + "KB\nWidth: " + img.width + "\nHeight: " + img.height);
}
img.src = _URL.createObjectURL(file);
}
You can make your function asynchronous with simply using an appropriate callback:
function loadImages(imgsrc, callback) {
var image = new Image();
image.onload = callback;
image.src = imgsrc;
}
and then you can call this function easily like this
loadImages('you image src', function() {
// whatever code to be executed
});
Hope if works for you.
The main problem is that I have to work with many images. And I can't use crossOrigin Attribute for all of them.
My code looks like this:
<script>
var c=document.getElementById('example');
var ctx=c.getContext('2d');
var LeftHand = new Image();
LeftHand.id="imq1";
var RightHand = new Image();
RightHand.id="imq2";
var Body = new Image();
Body.id="imq6";
boyBody.src = "https://getout-s3.s3.amazonaws.com/baseBody/boy-02.png";
LeftHand.src = "https://getout-s3.s3.amazonaws.com/NK4XtQvkZ4MGctZf_.hand(unisex)_13.png ";
RightHand.src = "https://getout-s3.s3.amazonaws.com/OPdFPcU2sORgNmTy_.hand(unisex)_9.png ";
Body.src = "https://getout-s3.s3.amazonaws.com/HRZqrTYSdJXGedgX_.Body_(m)7.png ";
boyBody.onload = function() {
ctx.drawImage(boyBody, 0, 0, boyBody.width/2, boyBody.height/2);
ctx.drawImage(LeftHand, (899 - LeftHand.width/2)/2, (867 - LeftHand.height/2)/2, LeftHand.width/2, LeftHand.height/2);
ctx.drawImage(Underwear, (599 - Underwear.width/2)/2, (845 - Underwear.height/2)/2, Underwear.width/2, Underwear.height/2);
ctx.drawImage(Body, (599 - Body.width/2)/2, (557 - Body.height/2)/2, Body.width/2, Body.height/2);
var img = c.toDataURL("image/png");
document.write('<img src="' + img + '" />');
};
</script>
Browsers don't let programmers export cross-domain content for very good security reasons. Your private banking info is cross-domain content that you don't want give to thieves using the canvas as an export device.
Therefore, context.toDataURL is disabled immediately after you drawImage a cross-domain image onto canvas. The same disabling is true for context.getImageData. (context.getImageData is another way to export canvas content).
To allow exporting the canvas content to your users, you will have to host all the images on the same domain as your webpage.
BTW, you must give all your elements time to load before drawing them. Here's an image loader that loads all your images in advance and then calls start() when all the images are fully loaded. Put your ctx.drawImage's in start().
// put the paths to your images in imageURLs[]
var imageURLs=[];
imageURLs.push("https://getout-s3.s3.amazonaws.com/baseBody/boy-02.png");
imageURLs.push("https://getout-s3.s3.amazonaws.com/NK4XtQvkZ4MGctZf_.hand(unisex)_13.png");
// ...etc, for all images
// the loaded images will be placed in imgs[]
var imgs=[];
var imagesOK=0;
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
function start(){
// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
}
I'm uploading images and the processing part takes time which I can only detect client side by it being there. So I use this script
function: loadImage(src, callback){
var i = new Image(),
that = this;
i.onload = function(){
//we might get a 1 pixel image back from the webserver in case of a 404, which might also get cached
if(i.width <= 1){
setTimeout(function(){
var newSrc = (src.indexOf('?') > -1? src.substring(0,src.indexOf('?')) : src) + '?rnd=' + new Date().getMilliseconds();
i.src=null;
i.src = newSrc;
},5000);
return;
}
callback(i);
};
//sometimes images are not there yet because they are being processed. So we have to rerun the function every x seconds
i.onerror = setTimeout(function(){
var newSrc = (src.indexOf('?') > -1? src.substring(0,src.indexOf('?')) : src) + '?rnd=' + new Date().getMilliseconds();
i.src=null;
i.src = newSrc;
},5000);
i.src = src;
}
So, many webservers return a 1pixel image when an image returns a 404 to prevent the ugly broken image thing and in that case I want to do another round until I get something else.
However when the onload handler is being called and I reset the src, it doesn't lead to a new image load. Any suggestions on this?
i think there should be an easy solution for this, but I can't figure it out.
What I'm trying to do is to get the width/height of an image by its path (not rendered on screen).
Like:
var img = ImageInfo(path);
alert(img.width);
(I want to do this in plain javascript)
You can do something like this:
function getImageSize(imgSrc) {
var imgLoader = new Image(); // create a new image object
imgLoader.onload = function() { // assign onload handler
var height = imgLoader.height;
var width = imgLoader.width;
alert ('Image size: '+width+'x'+height);
}
imgLoader.src = imgSrc; // set the image source
}
You basically create a new image using javascript. Assign the onload event, and then set the source and wait for image to load. when it's loaded the onload handler alerts the height and width of the image. check this jsFiddle
Let ImageInfo function to accept a callback(ie: make it async).
function ImageInfo(path, onLoad) {
var img = new Image();
img.src = path;
img.onload = function() {
onLoad(img);
}
}
Use it like:
ImageInfo(url, function(img) {
alert(img.width);
});
Try this:
var path = "http://images2.wikia.nocookie.net/__cb20110928222437/callofduty/images/4/4f/Personal_IW_FTW_Awesome_Face_100px.png";
var img = new Image();
img.src = path;
It's pretty simplified, but something alone these lines should work.
http://jsfiddle.net/s9QVp/1/