I cannot get my image to display in an HTML canvas using drawImage(). I know the filepath is correct because the image displays just fine when I disable display: none;
I know this can occur when you attempt to draw an image before it is loaded, which you can avoid by using the onload property.
Here is the relevant HTML.
<canvas id='gameScreen'></canvas>
<img id="imgBall"src="assets/images/ball2.png" alt="ball">
<script type="module"src="src/index.js"></script>
Here is the relevant Javascript.
// CANVAS SETUP
let canvas = document.getElementById("gameScreen");
canvas.width = 800;
canvas.height = 600;
let ctx = canvas.getContext("2d");
// DISPLAY BALL
let imgBall = document.getElementById('imgBall');
imgBall.onload = function() {
console.log(imgBall.src + ' successfully loaded');
ctx.drawImage(imgBall, 10, 10);
}
imgBall.onerror = function() {
console.log(imgBall.src + ' failed to load');
}
What makes this so confusing to me is that I'm not getting any console messages from imgBall.onload, or from imgBall.onerror.
I'm pretty new to Javascript and canvas, so I apologize if the answer is extremely obvious.
To fix the issue I am dynamically creating an image tag and then giving it a src AFTER I have added the event handlers for error and onload.
This makes me think that the issue is due to the image loading BEFORE your script tag had a chance to add the event listeners to the img tag.
// CANVAS SETUP
let canvas = document.getElementById("gameScreen");
canvas.width = 800;
canvas.height = 600;
let ctx = canvas.getContext("2d");
// DISPLAY BALL
const imgBall = document.createElement("img");
imgBall.onload = function() {
console.log(imgBall.src + ' successfully loaded');
ctx.drawImage(fitImageOntoCanvas(imgBall,25,25), 10, 10);
}
imgBall.onerror = function() {
console.log(imgBall.src + ' failed to load');
}
imgBall.src = "https://pngimg.com/uploads/football/football_PNG52737.png"
// need to resize because my ball image is huge
// thanks #markE https://stackoverflow.com/questions/38664890/resize-images-with-canvas-before-uploading
function fitImageOntoCanvas(img,MAX_WIDTH,MAX_HEIGHT){
// calculate the scaling factor to resize new image to
// fit MAX dimensions without overflow
var scalingFactor=Math.min((MAX_WIDTH/img.width),(MAX_HEIGHT/img.height))
// calc the resized img dimensions
var iw=img.width*scalingFactor;
var ih=img.height*scalingFactor;
// create a new canvas
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
// resize the canvas to the new dimensions
c.width=iw;
c.height=ih;
// scale & draw the image onto the canvas
ctx.drawImage(img,0,0,iw,ih);
// return the new canvas with the resized image
return(c);
}
<canvas id="gameScreen" height="500" width="500"></canvas>
Related
I have created a basic shape in HTML canvas element which works fine.
The problem occurs when I resize the canvas, all the drawing in the canvas disappears. Is this the normal behavior? or is there a function that can be used to stop this?
One way to fix this could be to call drawing function again on canvas resize however this may not be very efficient if there is huge content to be drawn.
What's the best way?
Here is the link to sample code https://gist.github.com/2983915
You need to redraw the scene when you resize.
setting the width or height of a canvas, even if you are setting it to the same value as before, not only clears the canvas but resets the entire canvas context. Any set properties (fillStyle, lineWidth, the clipping region, etc) will also be reset.
If you do not have the ability to redraw the scene from whatever data structures you might have representing the canvas, you can always save the entire canvas itself by drawing it to an in-memory canvas, setting the original width, and drawing the in-memory canvas back to the original canvas.
Here's a really quick example of saving the canvas bitmap and putting it back after a resize:
http://jsfiddle.net/simonsarris/weMbr/
Everytime you resize the canvas it will reset itself to transparant black, as defined in the spec.
You will either have to:
redraw when you resize the canvas, or,
don't resize the canvas
One another way is to use the debounce if you are concerned with the performance.
It doesnt resize or redraw every position you are dragging. But it will resize only when the it is resized.
// Assume canvas is in scope
addEventListener.("resize", debouncedResize );
// debounce timeout handle
var debounceTimeoutHandle;
// The debounce time in ms (1/1000th second)
const DEBOUNCE_TIME = 100;
// Resize function
function debouncedResize () {
clearTimeout(debounceTimeoutHandle); // Clears any pending debounce events
// Schedule a canvas resize
debounceTimeoutHandle = setTimeout(resizeCanvas, DEBOUNCE_TIME);
}
// canvas resize function
function resizeCanvas () { ... resize and redraw ... }
I had the same problem. Try following code
var wrapper = document.getElementById("signature-pad");
var canvas = wrapper.querySelector("canvas");
var ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
It keeps the drawing as it is
One thing that worked for me was to use requestAnimationFrame().
let height = window.innerHeight;
let width = window.innerWidth;
function handleWindowResize() {
height = window.innerHeight;
width = window.innerWidth;
}
function render() {
// Draw your fun shapes here
// ...
// Keep this on the bottom
requestAnimationFrame(render);
}
// Canvas being defined at the top of the file.
function init() {
ctx = canvas.getContext("2d");
render();
}
I had the same problem when I had to resize the canvas to adjust it to the screen.
But I solved it with this code:
var c = document.getElementById('canvas');
ctx = c.getContext('2d');
ctx.fillRect(0,0,20,20);
// Save canvas settings
ctx.save();
// Save canvas context
var dataURL = c.toDataURL('image/jpeg');
// Resize canvas
c.width = 50;
c.height = 50;
// Restore canvas context
var img = document.createElement('img');
img.src = dataURL;
img.onload=function(){
ctx.drawImage(img,20,20);
}
// Restote canvas settings
ctx.restore();
<canvas id=canvas width=40 height=40></canvas>
I also met this problem.but after a experiment, I found that Resizing the canvas element will automatically clear all drawings off the canvas!
just try the code below
<canvas id = 'canvas'></canvas>
<script>
var canvas1 = document.getElementById('canvas')
console.log('canvas size',canvas1.width, canvas1.height)
var ctx = canvas1.getContext('2d')
ctx.font = 'Bold 48px Arial'
var f = ctx.font
canvas1.width = 480
var f1 = ctx.font
alert(f === f1) //false
</script>
First of all I've looked through all the similar questions and tried multiple times to get this to work but have had no luck. I'm trying to take a signature that I capture via a canvas element on either a desktop or mobile device and resize it. Because the device sizes are different, so is my canvas for each device. Before I save the signature image, I want to resize it so that all my saved images are the same size.
Here is the code I currently have.
resize(){
var image = new Image();
var t = this;
image.onload = function(){
image.width = '100px';
image.height = 'auto';
t.canvas.width = image.width;
t.canvas.height = image.height;
t.ctx.drawImage(image, 0,0);
console.log(t.canvas.toDataURL());
return t.canvas.toDataURL();
}
image.src = this.canvas.toDataURL("image/png");
}
This code doesn't produce any errors, however after I "resize" the image, canvas.toDataURL(); returns "data:," rather than the image. Before I attempt the resize, I am able to grab a valid png image from this.canvas.toDataURL();.
I also tried changing the style width and height but this causes my canvas to reset which causes my image to disappear.
this.canvas.style.width = 100;
this.canvas.style.height = 100;
Any help would be appreciated.
UPDATE
I've put together a Codepen here that shows the original image on the left and on the right you will see that same image that I have attempted to resize with JavaScript. I added an orange background for readability purposes only.
Codepen
The only problem I could spot in your codepen is this line
context.drawImage(img,200,150);
The values 200 and 150 specify the position on the canvas where the image should be drawn. This essentially draws it ouside the visible area.
If you change it to
context.drawImage(img, 0, 0, img.width, img.height);
it works as the second pair of numbers is the clipping area.
Here's an example:
var canvas = document.getElementById("can");
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
canvas.width = 200;
canvas.height = 150;
img.width = 200;
img.height = 150;
context.drawImage(img, 0, 0, img.width, img.height);
}
img.src = document.getElementById("theImg").src;
canvas {
background: orange;
}
<img id="theImg" src="data:image/png;base64,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">
<canvas id="can"></canvas>
I am attempting to resize an image's dimensions, whilst retaining it's aspect ratio. This seems like a very simple task, but I cannot find a rellevent answer anywhere.. (relating to JavaScript's Image() object). I'm probably missing something very obvious. Below is what I am trying to achieve:
var img = new window.Image();
img.src = imageDataUrl;
img.onload = function(){
if (img.width > 200){
img.width = 200;
img.height = (img.height*img.width)/img.width;
}
if (img.height > 200){
img.height = 200;
img.width = (img.width*img.height)/img.height;
}
};
This is to proportionally resize an image before being drawn onto a canvas like so: context.drawImage(img,0,0,canvas.width,canvas.height);.However it would appear I cannot directly change Image()dimensions, so how is it done? Thanks.
Edit: I haven't correctly solved the image proportions using cross-multiplication. #markE provides a neat method of obtaining the correct ratio. Below is my new (working) implementation:
var scale = Math.min((200/img.width),(200/img.height));
img.width = img.width*scale;
img.height = img.height*scale;
clearCanvas(); //clear canvas
context.drawImage(img,0,0,img.width,img.height);
Here's how to scale your image proportionally:
function scalePreserveAspectRatio(imgW,imgH,maxW,maxH){
return(Math.min((maxW/imgW),(maxH/imgH)));
}
Usage:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/balloon.png";
function start(){
canvas.width=100;
canvas.height=100;
var w=img.width;
var h=img.height;
// resize img to fit in the canvas
// You can alternately request img to fit into any specified width/height
var sizer=scalePreserveAspectRatio(w,h,canvas.width,canvas.height);
ctx.drawImage(img,0,0,w,h,0,0,w*sizer,h*sizer);
}
function scalePreserveAspectRatio(imgW,imgH,maxW,maxH){
return(Math.min((maxW/imgW),(maxH/imgH)));
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<h4>Original Balloon image resized to fit in 100x100 canvas</h4>
<canvas id="canvas" width=100 height=100></canvas>
The image dimensions are set in the constructor
new Image(width, height)
// for proportionally consistent resizing use new Image(width, "auto")
or
the context.drawImage()
the arguments are as follows:
context.drawImage(image source, x-coordinate of upper left portion of image,
y-coordinate of upper left portion of image,image width,image height);
simply position the the image with the first two numeric coordinates and then manually adjust the size with the last two (width,height)
//ex.
var x = 0;
var y = 0;
var img = new Image (200, "auto");
img.src = "xxx.png";
context.drawImage(img,x,y,img.width,img.height);
I'm currently attempting to dynamically retrieve the location of an image and load it into a html5 canvas. The canvas is in a bootstrap responsive environment hence I never know the actual width of the canvas until the document is ready. Using the code below I've managed to resize the image and canvas to what I require but the image quality is very poor. I'm thinking it is because of the vast reduction in size but again unfortunately I have no control over the size of the original image uploaded.
function load_canvas_image(photo_type, vehicle_index) {
image_location = get_image_location(photo_type, vehicle_index);
var img = new Image();
img.src = image_location;
var canvas = $("#myCanvas")[0];
var canvas_context = canvas.getContext("2d");
canvas_width = canvas.width;
canvas_height = canvas.height;
img.onload = function() {
cur_height = img.height;
cur_width = img.width;
aspect_ratio = cur_width/canvas_width;
new_height = cur_height/aspect_ratio;
canvas.height = new_height;
canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height);
}
};
$(document).on("change", "#add_damage_location", function() {
load_canvas_image($(this).val(), $('#vehicle_index').val());
});
I'm hoping someone knows how to use a similar method to reduce the width and height of an image using a similar method to the above whilst keeping the quality of the image as good as possible, I know to expect some reduction in quality but in it's current state it is unusable.
Thanks in Advance
I'm building a jQuery plugin which watermarks images (and yes, i'm well aware of the multitudinal drawbacks of a javascript/html5 watermarking system but just ignore that for now.) The basic method for each image is:
paste the image to the background of a canvas
add the data for a watermark image over that,
replace the src of the original image with that of the canvas (which now contains the watermark.)
Now it appears to work fine if I replace the image element with the canvas itself.. all of the elements appear on the canvas. But when I get the dataURL of the canvas, everything but the last image drawn onto it appears. I wouldn't even mind except this plugin also needs to replace the links to images as well, and so replace the hrefs with data urls (with the watermark.)
This is the current code:
(function($){
$.fn.extend({
cmark: function(options) {
var defaults = {
type: 'image',
content: 'watermark.png',
filter: 'darker',
scale:300,
box: {
top : 0.5,
left : 0.5,
width : 0.75,
height : 0.75,
bgcolor : '#000000',
bgopacity : 0.5,
fgopacity : 1
},
callback_unsupported: function(obj){
return obj;
}
}
var getScale = function(w, h, scale){
ratio = Math.min(scale/w, scale/h);
scalew = Math.round(ratio*w);
scaleh = Math.round(ratio*h);
return [scalew,scaleh];
}
var options = $.extend(defaults, options);
return this.each(function() {
obj = $(this);
canvas = document.createElement('canvas');
if(!window.HTMLCanvasElement){
return options.callback_unsupported(obj);
}
/* if selecting for images, reset the images. Otherwise,
we're replacing link hrefs with data urls. */
if(obj.attr('src')){
target_img = obj.attr('src');
}
else if (obj.attr('href')){
target_img = obj.attr('href');
}
// get the filetype, make sure it's an image. If it is, get a mimetype. If not, return.
ftype = target_img.substring(target_img.lastIndexOf(".")+1).toLowerCase();
canvasbg = new Image();
canvasbg.onload = function(){
iw = canvasbg.width;
ih = canvasbg.height;
scale = getScale(iw, ih, options.scale);
iw = scale[0];
ih = scale[1];
canvas.setAttribute('width', iw);
canvas.setAttribute('height', ih);
ctx = canvas.getContext('2d');
/* define the box as a set of dimensions relative to the size of the image (percentages) */
bw = Math.round(iw * options.box.width);
bh = Math.round(ih * options.box.height);
// for now the box will only ever be centered.
bx = Math.round((iw * options.box.top) - (bw/2));
by = Math.round(ih * options.box.left - (bh/2));
/* draw the box unless the opacity is 0 */
if(options.box.bgopacity > 0){
ctx.fillStyle = options.box.bgcolor;
ctx.globalAlpha = options.box.bgopacity;
ctx.fillRect(bx, by, bw, bh);
}
wm = new Image();
wm.onload = function(){
ww = wm.width;
wh = wm.height;
scalar = Math.max(bw, bh); // scale to within the box dimensions
scale = getScale(ww, wh, scalar);
ww = scale[0];
wh = scale[1];
ctx.globalCompositeOperation = options.filter;
ctx.drawImage(wm, bx, by, ww, wh);
}
wm.src = options.content;
ctx.drawImage(canvasbg, 0, 0, iw, ih);
obj.replaceWith(canvas);
$('body').append('<img src="'+canvas.toDataURL()+'">');
//obj.attr('src', canvas.toDataURL());
}
canvasbg.src = target_img;
});
}
})
})(jQuery);
I added a line which dumps an image with the data url directly onto the page for testing and this is what I see... on the left is the canvas element, on the right is the image with the data url:
So yeah, this has had me stumped for a couple of days now. I'm probably missing something horribly obvious but I can't see it.
... edited because the example is no longer online. sorry.
First of all, don't build a string buffer that big for a tag.
var img = new Image();
img.src = canvas.toDataURL();
$('body').append(img);
Or if you prefer:
$('body').append($('<img>').attr('src', canvas.toDataURL()))
Second, you are getting there dataURL of the canvas before you draw the watermark. The drawing happens in the wm.onload callback function, which happens when the watermark loads. That may not fire until way after canvasbg.onload fires off, which is where you get the dataURL.
So move the image append into code at the end of the wm.onload callback and you should be good.