Creating image from canvas results in blank image in firefox - javascript

Okay I found out what the problem was. Every time you say new Image() you HAVE to use the onload handler to ensure that the image has really load. Even if you assign the src attr via toDataURL.
I want to get a subimage of a given image.
In Google Chrome when I type console.log(createSubImg(img, 0, 0, 20, 20));
I can see the image. In Firefox I see an empty image.
What did I wrong?
My method looks like:
function createSubImg(img, x, y, width, height) {
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(
img,
x * width,
y * height,
width,
height,
0,
0,
width,
height);
var result = new Image();
result.src = canvas.toDataURL();
return result;
}

It works for me like this:
var img;
(function(){
img = document.getElementById('example');
img.onload = function(){
console.log(createSubImg(img, 0, 0, 20, 20));
};
});
and if I write console.log(createSubImg(img, 0, 0, 20, 20)); in Firefox it works too.

Here Is The Solution
<body>
<form id="form1" runat="server" style="position: relative;">
<img id="scream" width="220" height="277" src="Images/01.jpg" alt="The Scream" />
<img id="test" src="#" />
</form>
Script part is here
<script type="text/javascript">
$(function () {
var canvas = document.createElement('canvas');
var img = document.getElementById("scream");
var ctx = canvas.getContext("2d");
var res = createSubImg(img, 0, 0, 200, 200, canvas, ctx);
var myImage = $("#test");
myImage.attr('src', res.src);
});
function createSubImg(img, x, y, width, height, canvas, ctx) {
canvas.width = width;
canvas.height = height;
ctx.drawImage(
img,
x * width,
y * height,
width,
height,
0,
0,
width,
height);
var result = new Image();
result.src = canvas.toDataURL();
return result;
}
</script>

Related

JS use drawImage(Image,...) in Image.onload in screenshot codes

I'm reading chrome extension codes for capturing full page screenshot and here is a piece of codes I cannot figure out the logic behind (https://github.com/erichua23/prj/blob/676e98366c6a25c56b2e342a3aecec76ae076391/screenshot/background.js#L63):
chrome.tabs.captureVisibleTab(this.tabId, { format: "png" }, function(img) {
var blockImg = new Image();
var canvas = self.canvas;
if (Capturer.yPos + Capturer.clientHeight >= Capturer.scrollHeight) {
blockImg.onload = function() {
var ctx = canvas.getContext("2d");
var y = Capturer.clientHeight - Capturer.scrollHeight % Capturer.clientHeight;
ctx.drawImage(blockImg, 0, 0, width, height, 0, self.yPos - y, width, height);
Capturer.postImg();
};
} else {
blockImg.onload = function() {
var ctx = canvas.getContext("2d");
ctx.drawImage(blockImg, 0, 0, width, height, 0, Capturer.yPos, width, height);
Capturer.yPos += Capturer.clientHeight;
self.scrollPage(self.tabId, 0, Capturer.clientHeight);
};
}
blockImg.src = img;
});
Why putting a blank image on the canvas? And how the screenshot is obtained?
Thank You for your time and expertise.

Canvas doesn't work well with bootstrap

Hi i have problem with the tag Canvas.
I'm using bootstrap and i want create a canvas with an image where i can draw a dots after click with the mouse but because i'm using bootstrap the canvas area stretch and the dots are not in the same place i have click with the mouse
$().ready(function() {
showImage();
$("#image").click(function(e) {
getMousePositionAtClick(e);
});
function showImage() {
var canvas = document.getElementById('image');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'images/Piantina.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
};
}
function getMousePositionAtClick(e) {
var rect = image.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
alert(rect.left);
alert(rect.top);
drawPoint(x, y);
}
function drawPoint(x, y) {
var ctx = document.getElementById("image").getContext("2d");
ctx.fillStyle = "#000";
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2, true);
ctx.fill();
}
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-lg-8" id="columnCanvas">
<div class="card card-body">
<canvas id="image"></canvas>
</div>
</div>
As mentioned in comments above, a Canvas element is not responsive. Bootstrap on the other hand is meant to be responsive,. So to stop the scaling we can set the size. Looking at the spec for Canvas, the default size if not specified is 300px / 150px.. So in theory if we just set the Canvas CSS size to 300px/150px, this will also prevent the scaling, below is an example.
$().ready(function() {
showImage();
$("#image").click(function(e) {
getMousePositionAtClick(e);
});
function showImage() {
var canvas = document.getElementById('image');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'images/Piantina.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
};
}
function getMousePositionAtClick(e) {
var rect = image.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
alert(rect.left);
alert(rect.top);
drawPoint(x, y);
}
function drawPoint(x, y) {
var ctx = document.getElementById("image").getContext("2d");
ctx.fillStyle = "#000";
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2, true);
ctx.fill();
}
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-lg-8" id="columnCanvas">
<div class="card card-body">
<canvas id="image" style="width:300px;height:150px"></canvas>
</div>
</div>

How do I extract a portion of an image in canvas and use it as background image for a div?

This is how my code looks:
document.addEventListener('DOMContentLoaded', function () {
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext("2d");
var imageData = ctx.getImageData(0, 0, 300, 300);
var tile = {
'id': 1,
'data': imageData,
'dataUrl': imageData.toDataUrl()
};
var div = document.createElement('div');
div.classList.add('tile');
grid.appendChild(div);
div.style.backgroundImage = ('url(' + tile.dataUrl + ')');
});
I'm trying to extract portion of the image on canvas, from (0,0) with height and width 300px, and convert that imageData object into a dataUrl to be used as a background of a div.
I get an error: imageData.toDataUrl() is not a function. How can I achieve this?
Thanks in advance!
toDataURL is an HTMLCanvasElement method you have to call it from the canvas element itself.
You could draw back your resulted imageData to the canvas after you changed its size to the wanted one, but the easiest solution is to use a second, off-screen canvas, where you will draw the first canvas thanks to the context.drawImage method:
// The crop function
var crop = function(canvas, offsetX, offsetY, width, height, callback) {
// create an in-memory canvas
var buffer = document.createElement('canvas');
var b_ctx = buffer.getContext('2d');
// set its width/height to the required ones
buffer.width = width;
buffer.height = height;
// draw the main canvas on our buffer one
// drawImage(source, source_X, source_Y, source_Width, source_Height,
// dest_X, dest_Y, dest_Width, dest_Height)
b_ctx.drawImage(canvas, offsetX, offsetY, width, height,
0, 0, buffer.width, buffer.height);
// now call the callback with the dataURL of our buffer canvas
callback(buffer.toDataURL());
};
// #main canvas Part
var canvas = document.getElementById('main');
var img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
canvas.getContext('2d').drawImage(this, 0, 0);
// set a little timeout before calling our cropping thing
setTimeout(function() {
crop(canvas, 100, 70, 70, 70, callback)
}, 1000);
};
img.src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
// what to do with the dataURL of our cropped image
var callback = function(dataURL) {
document.body.style.backgroundImage = 'url(' + dataURL + ')';
}
<canvas id="main" width="284" width="383"></canvas>

Resizing base64 image does not work in Firefox

I tried many different ways, but in Firefox, when I resize the first time, it returns a blank image:
function imageToDataUri(img, width, height) {
var canvas = document.createElement('canvas');
ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
setTimeout(function () {
cursorimg = canvas.toDataURL();
}, 500);
}
This is my function and I call it like this:
cursorImage.onload = function(){
imageToDataUri(cursorImage, width, height);
}
I had the exact same issue as you, and the issue disappeared when I created the canva outside the "onload" callback, like this:
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
cursorImage.onload = function(){
ctx.drawImage(img, 0, 0, width, height);
cursorimg = canvas.toDataURL();
}
I'm still a beginner in JavaScript, I can't explain why it worked...

Im having an issue displaying a image from a URL in HTML Canvas

As far as I can see my code is exactly like the code on W3schools except im making a new image instead of using one already in the html, but i cant get it to display anything
<body>
<center><canvas id="myCanvas" width="1000" height="750"></canvas></center>
<script>
function newImage(src, width, height) {
var img = document.createElement("img");
img.src = src;
img.width = width;
img.height = height;
return img;
}
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i = newImage("http://i.imgur.com/ELsS4mN.jpg", 1000, 750);
ctx.drawImage(i,0,0);
</script>
The problem appears because you return image object before it is fully downloaded. Because of that canvas fails to render image data as background image.
You should make use of onload callback function and drawImage only when image data is completely available. This should work:
function newImage(src, width, height, callback) {
var img = new Image();
img.width = width;
img.height = height;
img.onload = function () {
callback(img);
};
img.src = src;
}
var c = document.getElementById("myCanvas"),
ctx = c.getContext("2d");
newImage("http://i.imgur.com/ELsS4mN.jpg", 1000, 750, function(image) {
ctx.drawImage(image, 0, 0);
});
Note how instead of returning image from newImage function, you pass callback function in it and invoke it once download complete.
function newImage(src, width, height, callback) {
var img = new Image();
img.width = width;
img.height = height;
img.onload = function () {
callback(img);
};
img.src = src;
}
var c = document.getElementById("myCanvas"),
ctx = c.getContext("2d");
newImage("http://i.imgur.com/ELsS4mN.jpg", 1000, 750, function(image) {
ctx.drawImage(image, 0, 0);
});
<canvas id="myCanvas" width="1000" height="750"></canvas>

Categories

Resources