I have a canvas with an id called napkin. When I call the following function it is supposed to draw an image and the napkin canvas onto another canvas in memory. It works on every browser but IOS Safari. The operation does not seem to exceed the IOS memory cap for the canvas. I test this by calling k().toDataURL(). Any ideas?
function k() {
var canvas = document.createElement('canvas');
var napkin = document.getElementById("napkin");
var img = new Image();
img.src = picurl;
var ctx = canvas.getContext("2d");
var imgdata = new Image();
imgdata.src = napkin.toDataURL();
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
ctx.globalAlpha = 0.5;
ctx.drawImage(imgdata, 0, 0);
return canvas;
}
You need to wait for the image data to load before using it...
var img = new Image();
img.onload = function(){
// do stuff here with img
};
img.src = picurl;
// not here
Related
I'm trying to create a smaller thumbnail of an image on a canvas.
The thumbnail size I'd like is 200 x 200
According to the documentation it should be as easy as drawImage(img, 0, 0, 200, 200) but I get the same results here is my code:
_canvas = document.createElement('canvas'),
ctx = _canvas.getContext("2d"),
img = new Image();
img.onload = function() {
ctx.drawImage(this, 0, 0, 1200, 600);
var dataURL = _canvas.toDataURL();
// The above creates the first image
//Then while I'm still in the load method I attempt to save another size:
ctx.drawImage(this,0,0,300,300);
var dataThumbURL = _canvas.toDataURL();
}
I save both dataURL and dataThumbURL to the server and both images are the same size.
My assumption is ctx.drawImage could be repeated with just a different size. Any idea how I can achieve this?
The width and height parameters of the drawImage() method do not alter the dimensions of the canvas you draw onto. So if your source image is bigger than the canvas it will simply be cropped.
To have snapshots of different sizes, you need to change the dimensions of the canvas to the desired size prior calling drawImage().
Here's an example:
let image = new Image();
let _canvas = document.createElement('canvas');
let ctx = _canvas.getContext("2d");
image.crossOrigin = "";
image.onload = function() {
let img, dataURL;
_canvas.width = 200;
_canvas.height = 150;
ctx.drawImage(this, 0, 0, _canvas.width, _canvas.height);
dataURL = _canvas.toDataURL();
img = new Image();
document.body.appendChild(img);
img.src = dataURL;
_canvas.width = 40;
_canvas.height = 30;
ctx.drawImage(this, 0, 0, _canvas.width, _canvas.height);
dataURL = _canvas.toDataURL();
img = new Image();
document.body.appendChild(img);
img.src = dataURL;
}
image.src = "https://api.codetabs.com/v1/proxy?quest=https://picsum.photos/id/237/200/300";
I have to work with pdfmake to build a pdf preview within my laravel application. I am a javascript noob and going nuts to generate the dataURI for an image in b. Hope you can help me out.
How can I get that generated base64 into my docdefinition?
function convertImageToDataURL(src, callback, outputFormat) {
// Create an Image object
var img = new Image();
// Add CORS approval to prevent a tainted canvas
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.naturalHeight;
canvas.width = this.naturalWidth;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
// Mark the canvas to be ready for garbage
// collection
canvas = null;
};
img.src = src;
// make sure the load event fires for cached images too
if (img.complete || img.complete === undefined) {
// Flush cache
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
// Try again
img.src = src;
}
}
convertImageToDataURL(
'{{asset('storage/'.$report->author->enterprises->first()->logo_image)}}',
function(dataUrl) {
// console.log('RESULT:', dataUrl);
// Put dataUrl into DocDefinition here!?!?
// return dataUrl is undefined
}
);`
Okay. As I said: I am a javascript noob. So I changed the script to this one:
function convertImageToDataURL(imgSrc) {
img = new Image();
img.src = imgSrc;
img.crossOrigin = "Anonymous";
var canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/jpg");
canvas = null;
return dataURL;
}
It might not be beautyful nor elegant, but it works for me.
I am trying to take a pattern and apply it over a png image but only cover the non-transparent part of the image similar to this one.
http://jsfiddle.net/eLmmA/1/
$(function() {
var canvas = document.createElement('canvas');
canvas.width = 250;
canvas.height = 250;
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = 'http://i.stack.imgur.com/QtQrZ.png';
}
img.src = 'http://i.stack.imgur.com/MDGFY.jpg';
document.body.appendChild(canvas);
});
The example above is really close to what I want but I need to be able to use a smaller texture image and repeat it over the none pattern image. I am not familiar with how to use canvas properly but trying to learn more about it.
Thanks in advance!
Never mind I figured it out.
var canvas = document.createElement('canvas');
canvas.width = 250;
canvas.height = 250;
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
var ptrn = canvas_context.createPattern(img, 'repeat');
canvas_context.fillStyle = ptrn;
canvas_context.fillRect(0, 0, canvas.width, canvas.height);
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = $('#base_url').data('base')+'assets/themes/img/download.png';
}
img.src = $('#base_url').data('base')+'assets/uploads/thumbs/1381413411Purple-Night-Owls-thumb.jpg';
$('#itemPreview').html(canvas);
I have done lots of research, and i'v become completely stumped on this issue.
The code is supposed to resize the dataURL to 500x500px. However, it ends up with a blank image.
The original dataURL variable at the top of the code IS valid. I console.log it, and it works when opening it in the browser. So I don't think that's the issue.
$('#img-resizer .do-it').bindFirst("click", function () {
originalImg = $("#img-resizer img.original").cropper('getCroppedCanvas').toDataURL('image/jpeg');
var img = document.createElement("img");
img.src = originalImg;
var canvas = document.createElement("canvas");
canvas.width = 500;
canvas.height = 500;
var ctx = canvas.getContext("2d");
ctx.width = 500;
ctx.height = 500;
ctx.drawImage(img, 0, 0, 500, 500);
cropImg = canvas.toDataURL("image/png");
$($("#img-resizer").attr("save-to")).attr("src", cropImg);
});
So what ends up happening, is the cropImg variable is just a blank image when opened in my browser.
As I said earlier, I am positive that the originalImg variable is valid, as I console.log it and it works when opened.
Thanks.
add load event. very important
remove unnecessary ctx.width/height
$('#img-resizer .do-it').bindFirst("click", function() {
originalImg = $("#img-resizer img.original").cropper('getCroppedCanvas').toDataURL('image/jpeg');
var img = document.createElement("img");
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = 500;
canvas.height = 500;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, 500, 500);
var cropImg = canvas.toDataURL("image/png");
$($("#img-resizer").attr("save-to")).attr("src", cropImg);
}
img.src = originalImg;
});
I'm trying to learn manipulate image and canvas in javascript. I'm wondering why we can not do :
var urlimg='http://images.aviary.com/imagesv5/feather_default.jpg';
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
}
img.src =urlimg ;
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
$('#image1').attr('src', img.src);
And we have to do this :
var urlimg='http://images.aviary.com/imagesv5/feather_default.jpg';
var can = document.getElementById('canvas');
var ctx = can.getContext('2d');
var img = new Image();
img.onload = function(){
can.width = img.width;
can.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src =urlimg ;
$('#image1').attr('src', img.src);
Is it due to time of image to load ?
Can I create a canvas from an existing object image ?
Thanks.
Is it due to time of image to load ?
Yes in part, but mostly because image loading is asynchronous so the next lines of code are executed right away while the image is loaded. To let you know an event is raised when it's done.
Can I create a canvas from an existing object image ?
No (not directly), but you can draw the image onto a canvas to initialize it (as you already do):
ctx.drawImage(imageElement, 0, 0, width, height);