I have come up with a function which transform the width and height of an image to new values,
function imageToDataUri(src, width, height) {
// create an off-screen canvas
var img=new Image();
img.src=src;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// set its dimension to target size
canvas.width = width;
canvas.height = height;
// draw source image into the off-screen canvas:
ctx.drawImage(img, 0, 0, width, height);
var d = ctx.getImageData(0, 0, width, height);
console.log('de from transformation is');
console.log(d);
return canvas.toDataURL();
}
The input to the function is a base64 string and the output is the same as well, but sometimes above function gives me a complete black image when I use my input image. Can someone tell me is there anything I am missing in my codes?
Related
I want to know how we can scale and crop an image in Javascript. I want to scale it down to 300x300px and crop it a little.
Do you have any suggestions ? I have the following code :
function cropImage(imagePath, newX, newY, newWidth, newHeight) {
//create an image object from the path
var img = document.createElement('img');
img.src = "data:image/png;base64,"+imagePath;
//alert(img.width);
//alert(img.height);
//initialize the canvas object
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
//set the canvas size to the new width and height
canvas.width = 300;
canvas.height = 300;
//draw the image
ctx.drawImage(img, newX, 75, 300, 300, 0, 0, 300, 300);
variables.imageCrop = canvas.toDataURL();}
Thank you !
Try it:
And learn more about .drawImage()
function cropImage(imagePath, leftRight, topBottom, newWidth, newHeight) {
const img = document.createElement('img');
img.src = imagePath;
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
img.addEventListener('load', function() {
//Set your canvas size as your choice
//here i just scaled by 10 with original dimension
canvas.width = img.naturalWidth*10;
canvas.height = img.naturalHeight*10;
const cropLeft = leftRight[0];
const cropRight = img.naturalWidth - leftRight[0] - leftRight[1];
const cropTop = topBottom[0];
const cropBottom = img.naturalHeight - topBottom[0] - topBottom[1];
ctx.drawImage(
img,
cropLeft,cropTop,
cropRight, cropBottom,
0,0, //here you can control placement of cropped image from left and top, by default it stays in 0,0 meaning the top left corner of the canvas
newWidth,newHeight //new width and height of cropped image
);
});
}
//Size of this image is 100x100 px
const img = "https://dummyimage.com/100.png/09f/fff";
//here [10,10] meaning crop 10px from left and 10px from right
//here [20,20] meaning crop 20px from top and 20px from bottom
cropImage(img,[10,10],[20,20], 100, 100);
html2canvas(document.querySelector("#capture")).then(canvas => {
document.querySelector(".canvas-layout").appendChild(canvas);
});
I need to resize this canvas (2304x1440 pixels to 230.4x144, for example) and scale back to the original 100% (2304x1440). How can I do that?
I use it for blur-effect on a background of the fixed header. Then scroll it with $(this).scrollTop(); The method is here.
After you get the canvas object from the html2canvas method, use its context to draw the canvas again in your desired resolution.
Like this for example,
function resizeCanvas(canvas, newHeight, newWidth)
{
var context = canvas.getContext('2d');
var imageData = context.getImageData(0, 0, canvas.width, canvas.width);
var newCanvas = document.createElement("canvas");
newCanvas.height = canvas.height;
newCanvas.width = canvas.width;
newCanvas.putImageData(imageData, 0, 0, 0, 0, newWidth, newHeight);
return newCanvas;
}
What is wrong with my code.I am trying to load the image background on a canvas and then draw few rectangles on the image canvas.my image is not showing up on the canvas or either is it being completely overwritten my rectangles.
I have followed this SO question, but still, it happens.
//Initialize a new Box, add it, and invalidate the canvas
function addRect(x, y, w, h, fill) {
var rect = new Box;
rect.x = x;
rect.y = y;
rect.w = w
rect.h = h;
rect.fill = fill;
boxes.push(rect);
invalidate();
}
// holds all our rectangles
var boxes = [];
// initialize our canvas, add a ghost canvas, set draw loop
// then add everything we want to intially exist on the canvas
function drawbackground(canvas,ctx,onload){
var img = new Image();
img.onload = function(){
// canvas.width = img.width;
// canvas.height = img.height;
ctx.drawImage(img);
//addRect(200, 200, 200, 200, '#FFC02B');
onload(canvas,ctx);
};
img.src = "https://cdnimages.opentip.com/full/VLL/VLL-LET-G.jpg";
}
function init() {
// canvas = fill_canvas();
canvas = document.getElementById('canvas');
HEIGHT = canvas.height;
WIDTH = canvas.width;
ctx = canvas.getContext('2d');
ghostcanvas = document.createElement('canvas');
ghostcanvas.height = HEIGHT;
ghostcanvas.width = WIDTH;
gctx = ghostcanvas.getContext('2d');
// make draw() fire every INTERVAL milliseconds
setInterval(draw, INTERVAL);
// set our events. Up and down are for dragging,
// double click is for making new boxes
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
canvas.ondblclick = myDblClick;
// add custom initialization here:
drawbackground(canvas,ctx);
//context.globalCompositeOperation = 'destination-atop';
// add an orange rectangle
addRect(200, 200, 200, 200, '#FFC02B');
// add a smaller blue rectangle
addRect(25, 90, 250, 150 , '#2BB8FF');
}
//wipes the canvas context
function clear(c) {
c.clearRect(0, 0, WIDTH, HEIGHT);
}
...
As the Image loads always asynchronously, and you draw your rects synchronously after drawbackground() call, you will get a canvas with only image on it.
You need to create function which will pe passed as third argument to drawbackground, and call addRect in this function instead of drawbackground
PS:
Your code should throw an exception because
onload(canvas,ctx);
will try to call undefined as a function
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>
Why does this canvas image not rotate correctly?
When I click the rotate button the image rotates but gets cropped weirdly. I want the image to stay intact and simply rotate.
Important: I'm not looking to rotate the div, I'm looking to rotate the actual image.
See fiddle:
http://jsfiddle.net/8V4V7/2/
Code:
function rotateBase64Image(base64data, callback) {
console.log("what we get: " + base64data);
var canvas = document.getElementById("dummyCanvas");
var ctx = canvas.getContext("2d");
var image = new Image();
image.src = base64data;
image.onload = function() {
ctx.translate(image.width, image.height);
ctx.rotate(Math.PI);
ctx.drawImage(image, 0, 0);
callback(canvas.toDataURL());
};
}
EDIT:
I need the image to rotate by 90 degrees on every click.
I tried the following but it doesn't work:
ctx.rotate(Math.PI/2);
This worked for me (I specified the height and width of the canvas inside the onload function):
function rotateBase64Image(base64data, callback) {
console.log("what we get: " + base64data);
var canvas = document.getElementById("dummyCanvas");
var ctx = canvas.getContext("2d");
var image = new Image();
image.src = base64data;
image.onload = function () {
canvas.height = image.height;
canvas.width = image.width;
ctx.translate(image.width, image.height);
ctx.rotate(Math.PI);
ctx.drawImage(image, 0, 0);
callback(canvas.toDataURL());
};
}
Edit
Updated function to rotate 90 degrees with every click (remove i in i*Math.PI to rotate 90 degrees only once)
var i = 0;
function rotateBase64Image(base64data, callback) {
console.log("what we get: " + base64data);
var canvas = document.getElementById("dummyCanvas");
var ctx = canvas.getContext("2d");
var image = new Image();
image.src = base64data;
image.onload = function() {
canvas.width = image.height;
canvas.height = image.width;
ctx.translate(canvas.width / 2, canvas.height / 2);
i++;
ctx.rotate(i*Math.PI/2);
ctx.translate(-canvas.width / 2, -canvas.height / 2);
ctx.drawImage(image, 0, 0);
};
}
Updated Fiddle
Just some supporting info for rotations, notably the saving of the context and how to rotate around the center of the image.
var context = canvas.getContext('2d');
//save the context
//pushes a Matrix on the transformation stack
context.save();
context.translate(x, y); //where to put image
context.rotate(angle); //angle in degrees (i think...)
context.scale(scale); //optional scale
//rotate around center of image
context.drawImage(bitmap, -image.width / 2, -image.height / 2);
//or rotate around top left corner of image
context.drawImage(image, 0, 0);
//restore the canvas
//pop a matrix off the transformation stack
context.restore();
References:
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations
http://html5.litten.com/understanding-save-and-restore-for-the-canvas-context/