HTML Canvas not displaying image - javascript

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?

Related

Javascript display dynamic changing image

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

HTML5/Javascript Image loading method & passing to variable

I have some code for loading images.
var assets = {
total:0,
success:0,
error:0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
};
function Loading(){
if (assets.success == assets.total){
if (stillLoading){
console.log("All assets loaded. Starting game.");
};
stillLoading = false;
return false;
}else{
stillLoading = true;
return true;
};
};
May still be inefficient, and ugly since I'm new to practicing javascript, open to suggestions. It loads the image and tells the main program when all the assets have finished loading through the function Loading(), and then adds the image to the object img.
I've been using this for a while now for my images, and it works.
For example, if I did.
LoadImage("Car", "imageOfCar.png");
ctx.drawImage(img.Car, 0, 0);
this would draw the image just fine to the canvas.
However, when I assign another variable the image, which for various reasons I want to do, such as assigning images to objects. e.g.
var secondCar = img.Car
then try to draw it.
ctx.drawImage(secondCar, 0, 0);
I get this error.
Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'
If it works for the initial variable, it should act the same way towards another variable that has just been assigned the exact same thing. So why is it am I getting this error?
If I was to load the image the typical way that doesn't check if it's finished loading.
img.Car = new Image();
img.Car.src = "imageOfCar.png";
secondCar = img.Car;
ctx.drawImage(secondCar);
This would work.
The behaviour here is a bit confusing, could someone explain to me what is happening, and perhaps suggest a way to fix it?
EDIT: Just to clarify.
This is the html file, called index.html.
<!DOCTYPE html>
<head>
<title>HTML5 Game Base</title>
<link rel = "stylesheet" type = "text/css" href = "styles.css">
</head>
<body>
<canvas id="screen" width="270" height="480" style="border:1px solid #000000;"></canvas>
<script src = "script.js"></script>
</body>
</html>
The canvas is set up as screen. All the javascript code I've displayed above takes place within script.js which is called in index.html.
This is how screen is called within the script.js.
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
This is what ctx.drawImage() is referencing.
I realize this won't be the most helpful answer, but I tinkered around with your code a little. This is what I used:
<!DOCTYPE html>
<head>
<title>HTML5 Game Base</title>
</head>
<body>
<canvas id="screen" width="270" height="480" style="border:1px solid #000000;"></canvas>
<script>
var stillLoading = true;
var img = {};
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
assets = {};
assets.total = 0;
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
//assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
}
</script>
</body>
</html>
Then in Chrome's console I typed
LoadImage("Car", "map.png");
LoadImage("un", "Untitled.png");
ctx.drawImage(img.Car, 0, 0);
ctx.drawImage(img.un, 0, 0);
and get the expected result of images loading in the canvas. Even when assigning one of the img images to a new variable, this works as expected.
var second = img.Car
ctx.drawImage(second, 0, 0)
It appears everything is working fine when run manually, so my guess would be timing. When are you running these commands? Are they in the js file or from the console?
It would appear your LoadImage function is fine. Sorry this is not super helpful, but hopefully will help you rule out where not to look for the problem.
One approach could be to utilize Promise , as load event of new Image is asynchronous secondCar could be undefined when used as parameter within setInterval, e.g., load event of img may not be complete when var secondCar = img.Car applied after call to LoadImage; also added variable reference for setInterval for ability to call clearInterval() if needed
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
var interval = null;
var assets = {
total: 0,
success: 0,
error: 0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path) {
return new Promise(function(resolve, reject) {
var toLoad = new Image();
assets.total++;
toLoad.addEventListener("load", function() {
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
// resolve `img` , `assets` object
resolve([img, assets])
}, false);
toLoad.addEventListener("error", function() {
assets.error++;
reject(assets)
}, false);
toLoad.src = path;
})
};
function Loading() {
if (assets.success == assets.total) {
if (stillLoading) {
console.log("All assets loaded. Starting game.");
};
stillLoading = false;
return false;
} else {
stillLoading = true;
return true;
};
};
var promise = LoadImage("Car", "http://pngimg.com/upload/audi_PNG1736.png");
promise.then(function(data) {
// `data` : array containing `img` , `assets` objects
console.log(data);
var secondCar = data[0].Car;
interval = setInterval(function() {
if (!(Loading())) {
ctx.drawImage(secondCar, 0, 0);
};
}, 1000 / 60);
});
<canvas id="screen" width="1000" height="700" style="border:1px solid #000000;"></canvas>
Solved. Turns out it was a timing issue. In the example I gave, when secondCar is assigned img.Car, img.Car had not yet loaded.
Instead I created a new function called Initialise(), and called it from within Loading(). So from now on I would just have to initialise all my variables that may require images from within Initialise(). This way, variables can only be assigned images after they've loaded.
New Code:
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
var assets = {
total:0,
success:0,
error:0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
};
function Loading(){
if (assets.success == assets.total){
if (stillLoading){
console.log("All assets loaded. Starting game.");
Initialise();
};
stillLoading = false;
return false;
}else{
stillLoading = true;
return true;
};
};
LoadImage("Car", "http://pngimg.com/upload/audi_PNG1736.png");
function Initialise(){
window.secondCar = img.Car;
};
setInterval(function(){
if (!(Loading())) ctx.drawImage(secondCar, 0, 0);
}, 1000/60);
Works now, thanks for the help although I ended up solving it myself. I would still appreciate any tips on how to improve it. Or knowing that I'm new to javascript, any nitpicks to help me conform to javascript conventions.

Canvas image moves slightly to right onload

I am working with the signature_pad lib to accept signature for my web app. I am having an issue after loading a saved signature.
Assuming I am working with a blank signaturePad, I create some signature and save it.
After refreshing the page, this is what shows up.
Notice it moves to the right and also seems like its zoomed in slightly.
Any idea why this may be happening? Here is some code I am working with:
<canvas class="signature-canvas" height="150" width="500" id="signatureCanvas"></canvas>
var canvas = document.querySelector("canvas#signatureCanvas");
scope.signaturePad = new SignaturePad(canvas);
scope.c2 = document.createElement('canvas');
scope.ctx = scope.c2.getContext('2d');
scope.img = new Image();
scope.img.crossOrigin = "Anonymous";
scope.img.onload = function() {
scope.drawSig();
}
scope.img.src = scope.signature;
scope.drawSig = function(){
scope.ctx.drawImage(scope.img, 0, 0);
scope.imgStr = scope.c2.toDataURL("image/png", "");
scope.signaturePad.fromDataURL( scope.imgStr );
};

Get image dimensions with JavaScript using innerHTML

I'm working on an AJAX function that receives image URLs. However, I won't be using a node append to insert it. I'm using innerHTML, which makes it difficult to get the file dimensions.
At the moment, I'm using a function which is returning somewhat mixed results. Sometimes it gets the actual dimensions, other times it returns "0" as the image dimensions.
This is my function:
var url = "http://placekitten.com.s3.amazonaws.com/homepage-samples/408/287.jpg";
var width = getDimensions(url)[0];
var height = getDimensions(url)[1];
var insert = '<img src="'+url+'" width="'+width+'" height="'+height+'" />';
function getDimensions(path) {
var img = new Image();
img.src = path;
return [img.width, img.height];
}
Not sure why it's acting inconsistently though. Does anyone have any suggestions?
I was thinking it might be something to do with the AJAX inserting the image before it loads the dimensions, although not really sure.
Here's a fiddle, which seems to work as expected, but like I said, it's inconsistent.
http://jsfiddle.net/aH5re/1/
EDIT
Here is a second fiddle with a much larger image. I noticed it's a lot more inconsistent than a smaller image file
http://jsfiddle.net/aH5re/2/
You'll have to wait for the image to finish loading before you can get the dimensions properly and reliably. What's currently happening is that it's returning the dimensions before the image is potentially fully loaded. If you have it already cached you may be getting correct dimensions but on a large image uncached you're not going to get reliable results.
Have a look at this demo about how you could perhaps achieve that.
http://jsfiddle.net/robschmuecker/aH5re/5/
Javascript:
var url = "http://www.hdwallpapers.in/download/transformers_4_age_of_extinction-2560x1440.jpg";
var div = document.querySelector('div');
alert('loading image now');
var button = document.querySelector('.test');
getDimensions(url);
button.addEventListener('click', function () {
div.innerHTML = insert;
});
function getDimensions(path) {
var img = new Image();
img.src = path;
img.onload = function () {
alert('loaded');
var width = img.width;
var height = img.height;
insert = '<img src="' + url + '" width="' + width + '" height="' + height + '" />';
button.disabled = false
};
}

Failed to load resource, Javascript, HTML5

I'm trying to get my Sprite to show up because I'm making a game using Javascript with HTML5. This has worked for me before a while back, but now then it stopped working, so I decided to rewrite the script again -- it still doesn't work. Not sure what the problem is, but here's the Javascript code, and then, the HTML code. Thanks! Also - I'm using Chrome. And the Sprite has showed up in the Chrome internet browser before.
The Javascript Code:
var canvasBg = document.getElementById('canvasBg');
var ctxBg = canvasBg.getContext('2d');
var clearCanvasBtn = document.getElementById('clearCanvasBtn');
clearCanvasBtn.addEventListener('click',clearCanvas,false);
var gameWidth = canvasBg.width;
var gameHeight = canvasBg.height;
var imgSprite = new Image();
imgSprite.src = 'sprite.png';
imgSprite.addEventListener('load',drawBg,false);
function drawBg() {
var srcX = 0;
var srcY = 0;
var drawX = 0;
var drawY = 0;
ctxBg.drawImage(imgSprite,srcX,scrY,gameWidth,gameHeight,drawX,drawY,gameWidth,game Height);
}
function clearCanvas() {
ctxBg.clearRect(0,800,500);
}`
HTML code...:
`
Youtube HTML5 Game Dev Tutorial
<button id="clearCanvasBtn" type="button">Clear Canvas</button>
<canvas id="canvasBg" width="800px" height="500px" style="display:block;background:#ffffff;margin:100px auto 0px;"></canvas>;
<script src="game tester.js"></script>
`
You didn't say what "stopped working" means, but...
There is a new bug in Chrome when creating Image objects
So, if your code worked fine before but fails after a Chrome update, try this:
// instead of new Image()
var imgSprite = document.createElement("img");

Categories

Resources