I want to make the context inside the canvas to rotate on button click, I'm pretty sure that I have to use onclick, but I don't know where to put it or what logic do I have to write inside it. Can anyone help me out?
I tried using jquery on click but that does not work:
HTML:
<input type="file" id="fileInp" onchange="readImage(this)">
<button type="button" class="rotate">Rotate</button>
<div>
<canvas id="canvasImg" style="max-width:100%; border:solid;" width="100%" height="100%"></canvas>
</div>
Javascript:
function readImage(input) {
const canvas = document.getElementById('canvasImg');
const context = canvas.getContext("2d");
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
context.clearRect(0, 0, canvas.width, canvas.height);
if (input.value !== '') {
imgSrc = window.URL.createObjectURL(input.files[0]);
}
const img = new Image();
img.onload = function() {
context.drawImage(img, 0, 0);
}
img.src = imgSrc;
}
jQuery('.rotate').on('click', function() {
degree = 90;
drawRotate(degree);
})
function drawRotate(degree) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(degrees * Math.PI / 180);
context.drawImage(image, -image.width / 2, -image.width / 2);
context.restore();
}
ok so there are a few problems in your code..
in the drawRotate function you use variables such as image, context, canvas which is never has declared..
you call the function param degree but use it as degreeS
you translate the context forward, but never return him back
maybe there was more and i forget..
shortly, please look at the attached code
<input type="file" id="fileInp" onchange="readImage(this)">
<button type="button" class="rotate" onclick="drawRotate(90)">Rotate</button>
<div>
<canvas id="canvasImg" style="max-width:100%; border:solid;" width="100%" height="100%"></canvas>
</div>
<script>
const canvas = document.getElementById('canvasImg');
const context = canvas.getContext("2d");
const input = document.getElementById('fileInp');
function readImage(input) {
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
context.clearRect(0, 0, canvas.width, canvas.height);
let imgSrc;
if (input.value !== '') {
imgSrc = window.URL.createObjectURL(input.files[0]);
}
const img = new Image();
img.onload = function() {
context.translate(canvas.width / 2, canvas.height / 2);
context.drawImage(img, -img.width / 2, -img.height / 2, img.width, img.height);
context.translate(-canvas.width / 2, -canvas.height / 2);
}
img.src = imgSrc;
}
function drawRotate(degree) {
let imgSrc;
if (input.value !== '') {
imgSrc = window.URL.createObjectURL(input.files[0]);
}
const img = new Image();
img.onload = function() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(degree * Math.PI / 180);
context.drawImage(img, -img.width / 2, -img.height / 2, img.width, img.height);
context.translate(-canvas.width / 2, -canvas.height / 2);
}
img.src = imgSrc;
}
</script>
play around rotate(-180deg) for continous rotation
function readImage(input) {
const canvas = document.getElementById('canvasImg');
const context = canvas.getContext("2d");
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
context.clearRect(0, 0, canvas.width, canvas.height);
if (input.value !== '') {
imgSrc = window.URL.createObjectURL(input.files[0]);
}
const img = new Image();
img.onload = function() {
context.drawImage(img, 0, 0);
}
img.src = imgSrc;
}
jQuery('.rotate').on('click', function() {
$("#canvasImg").css({'transform': 'rotate(-180deg)'});
})
function drawRotate(degree) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(degrees * Math.PI / 180);
context.drawImage(image, -image.width / 2, -image.width / 2);
context.restore();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="fileInp" onchange="readImage(this)">
<button type="button" class="rotate">Rotate</button>
<div>
<canvas id="canvasImg" style="max-width:100%; border:solid;" width="100%" height="100%"></canvas>
</div>
Related
I tried to load the image by url on the canvas. And I change the canvas size to image size. andf I tried to rotate the image but if I executed it, some part of the image is cropped. Please find the errors in my code.
if (submitBtn) {
submitBtn.addEventListener('click', handleSubmitBtnClick);
}
function handleSubmitBtnClick() {
let imgURLValue = inputImageURL.value;
backgroundImage.src = `${imgURLValue}`;
backgroundImage.crossOrigin = 'Anonymous';
backgroundImage.onload = function () {
canvas.width = backgroundImage.width;
canvas.height = backgroundImage.height;
ctx.drawImage(
backgroundImage,
0,
0,
backgroundImage.width,
backgroundImage.height
);
};
}
if (rotateBtn) {
rotateBtn.addEventListener('click', handleRotateBtn);
}
function handleRotateBtn() {
degree += 90;
if (degree >= 360) {
degree = 0;
}
if (degree === 0 || degree === 180) {
canvas.width = backgroundImage.width;
canvas.height = backgroundImage.height;
} else {
canvas.width = backgroundImage.height;
canvas.height = backgroundImage.width;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(backgroundImage.width / 2, backgroundImage.height / 2);
ctx.rotate((degree * Math.PI) / 180);
ctx.drawImage(
backgroundImage,
0,
0,
backgroundImage.width,
backgroundImage.height,
-backgroundImage.width / 2,
-backgroundImage.height / 2,
backgroundImage.width,
backgroundImage.height
);
ctx.restore();
}
[enter image description here][1]
If I rotate the image, the image is loaded like this..
[1]: https://i.stack.imgur.com/drNaG.png
The origin of your rotation should be the center of the canvas, so that it uses the updated width and height values.
By using the original center of the image your drawing will be offset.
const rotateBtn = document.querySelector("button");
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const backgroundImage = new Image();
backgroundImage.src = "https://picsum.photos/150/300";
backgroundImage.decode().then(() => {
rotateBtn.disabled = false;
handleRotateBtn();
});
let degree = -90;
if (rotateBtn) {
rotateBtn.addEventListener('click', handleRotateBtn);
}
function handleRotateBtn() {
degree += 90;
if (degree >= 360) {
degree = 0;
}
if (degree === 0 || degree === 180) {
canvas.width = backgroundImage.width;
canvas.height = backgroundImage.height;
} else {
canvas.width = backgroundImage.height;
canvas.height = backgroundImage.width;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
// use the updated center as origin
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate((degree * Math.PI) / 180);
// I simplified this call but it does the same as yours
ctx.drawImage(
backgroundImage,
-backgroundImage.width / 2,
-backgroundImage.height / 2
);
ctx.restore();
}
canvas { background: ivory }
<button disabled>rotate</button><br>
<canvas></canvas>
This question already has an answer here:
html5 canvas toDataURL returns blank image
(1 answer)
Closed 1 year ago.
I am trying to convert an image URL taken from firebase storage to a data URL. But when I opened the data URL, it displays a blank image in the new window. I need help to fix this issue.
var dataURL;
var imageurl;
var folder = formName + "/" + Insti + "/" + tenant + "/" + "Page 3";
var storageRef = firebase.storage().ref();
var listRef = storageRef.child(folder);
listRef.listAll()
.then((res) => {
res.items.forEach((itemRef) => {
itemRef.getDownloadURL().then(function(imageurl) {
console.log(imageurl)
var img = new Image();
var canvas = document.getElementById("image1");
var ctx = canvas.getContext("2d");
img.onload = function() {
canvas.height = canvas.width * (img.height / img.width);
var oc = document.createElement('canvas'),
octx = oc.getContext('2d');
oc.width = img.width * 0.5;
oc.height = img.height * 0.5;
octx.drawImage(img, 0, 0, oc.width, oc.height);
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5,
0, 0, canvas.width, canvas.height);
};
img.src = imageurl;
dataURL = canvas.toDataURL("image/png");
console.log(dataURL)
});
});
}).catch((error) => {
// Uh-oh, an error occurred!
});
<canvas width="300" height="200" id="image1"></canvas>
You invoke canvas.toDataURL() before the image is drawn to the canvas. So you export a blank canvas. Just move toDataURL inside the img.onload callback, that's it.
img.onload = function () {
canvas.height = canvas.width * (img.height / img.width);
var oc = document.createElement('canvas'),
octx = oc.getContext('2d');
oc.width = img.width * 0.5;
oc.height = img.height * 0.5;
octx.drawImage(img, 0, 0, oc.width, oc.height);
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5,
0, 0, canvas.width, canvas.height);
dataURL = canvas.toDataURL("image/png"); // <-- Here
console.log(dataURL);
};
img.src = imageurl;
I'm taking image input from user, then resizing and showing it on a canvas. Here is the code-
HTML-
<form class="cmxform">
<input type='file' id="Photo" />
<canvas id="canvas" width="300" height="200"></canvas>
</form>
JavaScript-
$("#Photo").change(function (e) {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function () {
ctx.drawImage(img, 0, 0, img.width, img.height, // source rectangle
0, 0, canvas.width, canvas.height); // destination rectangle
}
});
But here I'm loosing the aspect ratio. Is there any way to do it?
UPDATE-
I've got the answer from this sa question -
Here is a snippet to help you for that
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
var fill = true;
if (fill)
{
$('#fill').attr("disabled", true);
}
$("#Photo").change(function (e) {
img.src = URL.createObjectURL(e.target.files[0]);
img.onload = function () {
if (fill)
{
drowImageFill(img);
}
else
{
drowImageCenter(img);
}
}
});
$("#fill").click(function(){
//console.log("fill");
var input = document.getElementById('Photo');
if (input.files[0] !== undefined)
{
img.src = URL.createObjectURL(input.files[0]);
img.onload = function () {
drowImageFill(img);
}
}
$('#fill').attr("disabled", true);
$('#center').attr("disabled", false);
fill = true;
});
$("#center").click(function(){
//console.log("center");
var input = document.getElementById('Photo');
if (input.files[0] !== undefined)
{
img.src = URL.createObjectURL(input.files[0]);
img.onload = function () {
drowImageCenter(img);
}
}
$('#center').attr("disabled", true);
$('#fill').attr("disabled", false);
fill = false;
});
//ratio formula
//http://andrew.hedges.name/experiments/aspect_ratio/
function drowImageFill(img){
ctx.clearRect(0, 0, canvas.width, canvas.height);
//detect closet value to canvas edges
if( img.height / img.width * canvas.width > canvas.height)
{
// fill based on less image section loss if width matched
var width = canvas.width;
var height = img.height / img.width * width;
offset = (height - canvas.height) / 2;
ctx.drawImage(img, 0, -offset, width, height);
}
else
{
// fill based on less image section loss if height matched
var height = canvas.height;
var width = img.width / img.height * height;
offset = (width - canvas.width) / 2;
ctx.drawImage(img, -offset , 0, width, height);
}
}
function drowImageCenter(img)
{
ctx.clearRect(0, 0, canvas.width, canvas.height);
if( img.height / img.width * canvas.width < canvas.height)
{
// center based on width
var width = canvas.width;
var height = img.height / img.width * width;
offset = (canvas.height - height) / 2;
ctx.drawImage(img, 0, offset, width, height);
}
else
{
// center based on height
var height = canvas.height;
var width = img.width / img.height * height;
offset = (canvas.width - width) / 2;
ctx.drawImage(img, offset , 0, width, height);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="300" height="200" style="border:2px solid #000000;"></canvas>
<form class="cmxform">
<input type='file' id="Photo" />
</form>
<button id="fill">Fill</button>
<button id="center">Center</button>
I want to convert the rawImg to base64 and pass it on image.src. I will be needing the base64 dataURL to put effects on my canvas.
Pls see my code below:
function onLoad() {
canvas = document.querySelector("#myCanvas");
context = canvas.getContext("2d");
var image = new Image();
image.onload = function () {
if (image.width != canvas.width)
canvas.width = image.width;
if (image.height != canvas.height)
canvas.height = image.height;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0, canvas.width, canvas.height);
filterCanvas(imageFilter);
}
var rawImg = "flower.jpg";
imageURL = <-- (convert rawImg to base64.. I dont know what to write here)
image.src = imageURL;
}
Use HTMLCanvasElement.toDataURL(), returns a data URI containing a representation of the image in the format specified by the type parameter(The default type is image/png)
function onLoad() {
canvas = document.querySelector("#myCanvas");
context = canvas.getContext("2d");
var image = new Image();
image.onload = function() {
if (image.width != canvas.width)
canvas.width = image.width;
if (image.height != canvas.height)
canvas.height = image.height;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0, canvas.width, canvas.height);
filterCanvas(imageFilter);
var imageURL = canvas.toDataURL();
YOUR_IMAGE.src = imageURL; //Select `YOUR_IMAGE` using getElementById/querySelector/...
}
image.src = "flower.jpg";
}
With HTML snippets as:
<canvas id="myCanvas"></canvas>
<span>Resultant data URL: </span><span id="result"></span>
And, updating your javascript code as below:
canvas = document.querySelector("#myCanvas");
context = canvas.getContext("2d");
var image = new Image();
image.onload = function() {
if (image.width != canvas.width)
canvas.width = image.width;
if (image.height != canvas.height)
canvas.height = image.height;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0, 0, canvas.width, canvas.height);
// filterCanvas(imageFilter);
var imageURL = canvas.toDataURL();
alert(imageURL);
document.querySelector("#result").innerHTML = imageURL;
}
image.src = "flower.jpg";
You will get the resultant base64 string within the #result span element. Please try this.
I'm iplementing zoom out effect of an image. But after it's scaled and zoom out, the image isn't on center of canvas.
This is my code:
var canvas = document.getElementById('canvas');
var image = document.getElementById('image');
var ctx = canvas.getContext("2d");
var zoomDelta = 0.025; // 10 steps in 10s, scale from 5 to 1
var currentScale = 5;
var img = new Image();
img.src = image.src;
img.onload = function() {
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
}
$("#start").on("click", function () {
ctx.translate(canvas.width / 2, canvas.height / 2);
drawImage();
var zoom1 = window.setInterval(
function() {
if(currentScale < 1)
window.clearInterval(zoom1);
else
reDraw();
}, 50
);
});
function reDraw() {
currentScale -= zoomDelta;
drawImage();
}
function drawImage() {
clear();
ctx.save();
ctx.scale(currentScale, currentScale);
ctx.drawImage(img, -img.width / 2, -img.width / 2);
ctx.restore();
}
function clear() {
ctx.clearRect(-img.width / 2 - 2, -img.width / 2 - 2, img.width + 4, img.height + 4);
}
Thanks in advance.
Btw, this is its fiddle: http://jsfiddle.net/huynq/RK2D7/
Translate to the point on which you want to center the image.
A Demo: http://jsfiddle.net/m1erickson/QEuw4/
var cx=canvas.width/2;
var cy=canvas.height/2;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.translate(cx,cy);
ctx.scale(scale,scale);
ctx.drawImage(img,-img.width/2,-img.height/2);
ctx.restore();