I have a canvas that scales an image to fit inside of it, what I'm trying to do is export the image in a larger size than what the canvas is set to. I am using the canvas.toBlob method to get the blob data and am sending that to my server as an uploaded file.
For example, the canvas is 350px by 350px, I'd like to save the image as 800px by 1000px.
<canvas id="myCanvas" width="350" height="350"></canvas>
<script type="text/javasript">
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
var img_info = { width:527, height:350 };
var sourceX = 0;
var sourceY = 150;
var sourceWidth = 4520;
var sourceHeight = 3000;
var destWidth = img_info.width;
var destHeight = img_info.height;
var destX = canvas.width / 2 - destWidth / 2;
var destY = canvas.height / 2 - destHeight / 2;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
};
imageObj.src = 'hhttp://i.imgur.com/tKplLLb.jpg';
canvas.toBlob(
function (blob) {
var formData = new FormData();
formData.append('file', blob);
jQuery.ajax({
url: "test.php",
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function (res) {
}
});
},
'image/jpg'
);
</script>
This function takes a canvas and width+height parameters. It will return a new canvas element on which you can call toBlob
function getResizedCanvas(canvas,newWidth,newHeight) {
var tmpCanvas = document.createElement('canvas');
tmpCanvas.width = newWidth;
tmpCanvas.height = newHeight;
var ctx = tmpCanvas.getContext('2d');
ctx.drawImage(canvas,0,0,canvas.width,canvas.height,0,0,newWidth,newHeight);
return tmpCanvas;
}
Working example here: http://jsfiddle.net/L4dua/
Related
I am trying to crop an image with Javascript. I have croppr.js and it is sending the data and I was trying to crop the image so I can save it to a storage server with Base 64. I have read online about .drawimage(). I have tried:
function process(data) {
console.log("DATA:" + data)
var canvas = document.getElementById("canvas")
var context = canvas.getContext('2d');
var imageObj = new Image();
var zoom
imageObj.onload = function() {
context.width = data.width
context.height = data.height
// draw cropped image
var sourceX = data.x;
var sourceY = data.y;
var sourceWidth = data.width / 2;
var sourceHeight = data.height / 2;
var destWidth = sourceWidth;
var destHeight = sourceHeight;
var destX = 0;
var destY = 0;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
var dataurl = canvas.toDataURL('image/jpeg', 1.0)
console.log(dataurl)
};
imageObj.src = document.getElementsByTagName("img")[0].src;
console.log(imageObj.src)
}
data Contains X Y Height Width As an JSON array.
First I see is the:
context.width = data.width
context.height = data.height
Did you meant to do canvas instead?
Here is an example:
function process(data) {
var canvas = document.getElementById("canvas")
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
canvas.width = data.width
canvas.height = data.height
// draw cropped image
var w = data.width / 2;
var h = data.height / 2;
context.drawImage(img, data.x, data.y, w, h, 0, 0, w, h);
};
img.src = data.src;
}
process({x:0, y:0, width:600, height: 600, src: "http://i.stack.imgur.com/UFBxY.png"})
<canvas id="canvas"></canvas>
That is the only issue I could see on your code.
What is not clear is the data you use to call the process function
I'm trying to resize an image in the client side and then send it to my server. But the image is not all the times settled correctly to the canvas used to resize the image.
I already sent the image resize but i need to send it at least 2 times to work.
I put <p> labels in my html to verify the data of the image and i can see the data incomplete the first time i send it.
This is my html
function ResizeImage() {
var filesToUpload = document.getElementById('imageFile').files;
var file = filesToUpload[0];
console.log('Data');
// Create an image
var img = document.createElement("img");
// Create a file reader
var reader = new FileReader();
// Set the image once loaded into file reader
reader.onload = function(e) {
//HERE IN THIS PART, the e.target.result works strange
img.src = e.target.result;
var canvas = document.createElement("canvas");
//var canvas = $("<canvas>", {"id":"testing"})[0];
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// var MAX_WIDTH = 400;
// var MAX_HEIGHT = 400;
var width = 200;
var height = 200;
if (img.width > img.height) {
if (img.width > width) {
height *= height / img.width;
//width = width;
}
} else {
if (img.height > height) {
width *= height / img.height;
//height = height;
}
}
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/png");
console.log(dataurl);
canvas.toBlob((blob) => {
var fd = new FormData();
fd.append("name", "paul");
fd.append("image", blob);
fd.append("key", "××××××××××××");
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:5000/2");
xhr.send(fd);
}, "image/png", 1)
document.getElementById('output').src = dataurl;
var para = document.createElement("p");
var node = document.createTextNode(dataurl);
para.appendChild(node);
var element = document.getElementById("contenedor");
element.appendChild(para);
}
// Load files into file reader
reader.readAsDataURL(file);
}
<input type="text" name="fileName">
<input type="file" id="imageFile" name="sampleFile" accept="image/png" />
<input type='button' value='Upload!' onclick="ResizeImage()" />
<img src="" id="output">
<div id="contenedor"></div>
<hr>
I expect it works the first time i send the data to the server.
Img.src is asynchronous.
To verify this, replace 'img.src = e.target.result;' with
img.onload = function () { console.log('done')}
img.src = e.target.result;
console.log('src')
If done runs after src, you know that the image isn't loaded yet when you try to ctx.drawImage.
To fix, simply move all your resizing code into img.onload.
I want to check for the size of image, and then display the image as a cropped version by defining the set size(w*h).
How can i do this?
This is the code I have tried:
var filesSelected = document.getElementById("inputFileToLoad").files;
if (filesSelected.length > 0)
{
var fileToLoad = filesSelected[0];
if (fileToLoad.type.match("image.*"))
{
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent)
{
var imageLoaded = document.createElement("img");
imageLoaded.src = fileLoadedEvent.target.result;
document.body.appendChild(imageLoaded);
};
fileReader.readAsDataURL(fileToLoad);
}
}
<input type="file" onchange="handleFiles(this.files[0])" id="inputFileToLoad">
<canvas id="canvas"></canvas>
function handleFiles(fileToLoad) {
if (fileToLoad.type.match("image.*")) {
var fileReader = new FileReader();
fileReader.onload = function (fileLoadedEvent) {
var img = new Image();
img.onload = function () {
var canvas = document.getElementById("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// cropped = ctx.getImageData(x, y, crop_width, crop_height);
cropped = ctx.getImageData(500, 500, 200, 200);
// clearing is optional ... new img is over the old one
ctx.clearRect(0, 0, canvas.width, canvas.height);
// re-size canvas to croped img size
canvas.width = 200;
canvas.height = 200;
ctx.putImageData(cropped, 0, 0)
};
img.src = fileLoadedEvent.target.result;
};
fileReader.readAsDataURL(fileToLoad);
}
}
draw the imageLoaded into canvas of the size w*h shifted by some position
get the image data by yourcanvas.toDataUrl()
place the image data into image element
The function that does this
function getImagePortion(imgObj, newWidth, newHeight, startX, startY, ratio){
/* the parameters: - the image element - the new width - the new height - the x point we start taking pixels - the y point we start taking pixels - the ratio */
//set up canvas for thumbnail
var tnCanvas = document.createElement('canvas');
var tnCanvasContext = canvas.getContext('2d');
tnCanvas.width = newWidth; tnCanvas.height = newHeight;
/* use the sourceCanvas to duplicate the entire image. This step was crucial for iOS4 and under devices. Follow the link at the end of this post to see what happens when you don’t do this */
var bufferCanvas = document.createElement('canvas');
var bufferContext = bufferCanvas.getContext('2d');
bufferCanvas.width = imgObj.width;
bufferCanvas.height = imgObj.height;
bufferContext.drawImage(imgObj, 0, 0);
/* now we use the drawImage method to take the pixels from our bufferCanvas and draw them into our thumbnail canvas */
tnCanvasContext.drawImage(bufferCanvas, startX,startY,newWidth * ratio, newHeight * ratio,0,0,newWidth,newHeight);
return tnCanvas.toDataURL();
}
is step by step described here
Thank you guys,
Using Canvas is the right approach here. This is my final piece of code
Here is the final Code:
Ref Link
<html>
<title>
Upload Image
</title>
<div style="text-align: center">
<h1>: UPLOAD IMAGE : </h1>
</div>
<div>
<input type="file" id="imageLoader" name="imageLoader" onchange="checkFileDetails()"/>
<br/>
<h3>Horizontal<h3>
<canvas id="imageCanvas1"></canvas>
<br/>
<h3>Vertical<h3>
<canvas id="imageCanvas2"></canvas>
<br/>
<h3>Horizontal Small<h3>
<canvas id="imageCanvas3"></canvas>
<br/>
<h3>Gallery<h3>
<canvas id="imageCanvas4"></canvas>
</div>
<script>
//Check for the image Size and type
// Display Image in the required format
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage1, false);
var canvas1 = document.getElementById('imageCanvas1');
var ctx1 = canvas1.getContext('2d');
function handleImage1(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas1.width = 755;
canvas1.height = 450;
ctx1.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var imageLoader1 = document.getElementById('imageLoader');
imageLoader1.addEventListener('change', handleImage2, false);
var canvas2 = document.getElementById('imageCanvas2');
var ctx2 = canvas2.getContext('2d');
function handleImage2(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas2.width = 365;
canvas2.height = 450;
ctx2.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var imageLoader2 = document.getElementById('imageLoader');
imageLoader2.addEventListener('change', handleImage3, false);
var canvas3 = document.getElementById('imageCanvas3');
var ctx3 = canvas3.getContext('2d');
function handleImage3(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas3.width = 365;
canvas3.height = 212;
ctx3.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var imageLoader3 = document.getElementById('imageLoader');
imageLoader3.addEventListener('change', handleImage4, false);
var canvas4 = document.getElementById('imageCanvas4');
var ctx4 = canvas4.getContext('2d');
function handleImage4(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas4.width = 380;
canvas4.height = 380;
ctx4.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
</script>
Ok this is what I am trying to acchomplish, (As of Now)I have user select image and the image is resized and uploaded to server. What i would like to do is after the image is selected and resized then stop Script. Then i would like to create a function to upload resized image when i choose to. The reason is that i am going to add more inputs texts into my form and was user has finished completing I then want to upload image with the files. Note: I have not added the text inputs will do after just want to be able to sepearate the upload functions..I am not sure how to seperate the FormData post portion
JAVASCRIPT
<script>
function ResizeMe(){
var dataurl = null;
var uniq = 'id' + (new Date()).getTime();
var filesToUpload = document.getElementById('input').files;
var file = filesToUpload[0];
// Create an image
var img = document.createElement("img");
// Create a file reader
var reader = new FileReader();
// Set the image once loaded into file reader
reader.onload = function(e)
{
img.src = e.target.result;
img.onload = function () {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 200;
var MAX_HEIGHT = 400;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
dataurl = canvas.toDataURL("image/jpeg",.2);
var blobBin = atob(dataurl.split(',')[1]);
var array = [];
for(var i = 0; i < blobBin.length; i++) {
array.push(blobBin.charCodeAt(i));
}
var files = new Blob([new Uint8Array(array)], {type: 'image/jpg', name: "ddd"});
// Post the data
var fd = new FormData();
fd.append("image", files, uniq);
$.ajax({
url: 'http:///www.***/upload.php',
data: fd,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
$('#form_input')[0].reset();
location.reload();
}
});
} // img.onload
}
// Load files into file reader
reader.readAsDataURL(file);
}
</script>
The code sending the formdata is
$.ajax({
url: 'http:///www.***/upload.php',
data: fd,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
$('#form_input')[0].reset();
location.reload();
}
});
That code is the code that you will want to put in a separate function. To move it elsewhere, you have to make sure it still has access to all of the variables being sent, namely, fd. fd is connected to several variables, all leading back to canvas. You say that there will only be one canvas at a time, so we can make canvas a global variable, and then getting fd from anywhere will be easy.
<script>
//Moved to global so that sendFormStuff will see it
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
function ResizeMe(){
var dataurl = null;
var uniq = 'id' + (new Date()).getTime();
var filesToUpload = document.getElementById('input').files;
var file = filesToUpload[0];
// Create an image
var img = document.createElement("img");
// Create a file reader
var reader = new FileReader();
// Set the image once loaded into file reader
reader.onload = function(e)
{
img.src = e.target.result;
img.onload = function () {
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 200;
var MAX_HEIGHT = 400;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
} // img.onload
}
function sendFormStuff() {
var dataurl = canvas.toDataURL("image/jpeg",.2);
var blobBin = atob(dataurl.split(',')[1]);
var array = [];
for(var i = 0; i < blobBin.length; i++) {
array.push(blobBin.charCodeAt(i));
}
var files = new Blob([new Uint8Array(array)], {type: 'image/jpg', name: "ddd"});
// Post the data
var fd = new FormData();
fd.append("image", files, uniq);
$.ajax({
url: 'http:///www.***/upload.php',
data: fd,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
$('#form_input')[0].reset();
location.reload();
}
});
}
// Load files into file reader
reader.readAsDataURL(file);
}
</script>
So really all we did here was move the request code into a separate function, and make canvas and ctx (which you were declaring twice, btw) accessible by that function.
I'm trying to resize an image via HTML canvas, but when I display it, it displays all black.
My code
function onSuccess(imageData) {
var img = new Image();
img.src = imageData;
window.setTimeout(function() {
var maxSize = 200;
var canvas = document.createElement("canvas");
canvas.width = maxSize;
canvas.height = maxSize;
var ctx = canvas.getContext("2d");
ctx.drawImage(img.src, 0, 0, maxSize, maxSize);
dataurl = canvas.toDataURL("image/jpeg");
alert(dataurl);
}, 1000);
}
I'm not exactly sure what it is I'm doing incorrectly. Thanks for the help!