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.
Related
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>
I have javascript code that was running fine on the server for about 2 weeks. After an update of Chrome it stops working :(
function doUpload() {
var file = document.getElementById('fileToUpload').files[0];
EXIF.getData(file, function () {
var orientation = 0;
orientation = EXIF.getTag(this, "Orientation");
var dataUrl = "";
var img = document.createElement("img"); // Create an image
var reader = new FileReader(); // Create a file reader
reader.onload = function(e) { // Set the image once loaded into file reader
img.src = e.target.result;
var canvas = document.createElement("canvas");
var MAX_WIDTH = 1080; // Set Width and Height
var MAX_HEIGHT = 1080;
var width = img.width;
var height = img.height;
console.log(img.width);
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
....
The problem is that img.width and img.height are both 0. Because of that it is impossible to resize the image. If I add console.log(img) I get <img src="data:image/jpeg:base 64, 9/j/ 4xg....> so I guess the image is properly loaded into the file reader but than something prevents the code from working. I´m struggling with this from last week with no luck. Does anyone see the problem?
Thanks
edit
here is the working code:
function doUpload() {
var file = document.getElementById('fileToUpload').files[0];
EXIF.getData(file, function () {
var orientation = 0;
orientation = EXIF.getTag(this, "Orientation");
var dataUrl = "";
var img = document.createElement("img"); // Create an image
var reader = new FileReader(); // Create a file reader
reader.onload = function(e) { // Set the image once loaded into file reader
var canvas = document.createElement("canvas");
img.src = e.target.result;
img.onload = function(){
var MAX_WIDTH = 1080; // Set Width and Height
var MAX_HEIGHT = 1080;
var width = img.width;
var height = img.height;
console.log(img);
I have created a image select and resize (Client side) and upload to server. What I am asking for help is with image preview in iframe(resized) but cannot figure out. I will be only using Chrome desktop for this application. Qusetion is please help me with displaying resized image within my iframe here are my scripts below
HTML
<input type="file" input id="input" onchange="ClientSideResize()" name="Image" value="%%%img%%%"/>
HTML iframe
<img src="" id="image">
<iframe name="my_iframe" src="" id="my_iframe" style="visibility: hidden;"></iframe>
SCRIPT
<script>
function ClientSideResize(){
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 () {
canvas = document.createElement("canvas");
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",100);
var blobBin = atob(dataurl.split(',')[1]);
var array = [];
for(var i = 0; i < blobBin.length; i++) {
array.push(blobBin.charCodeAt(i));
}
files = new Blob([new Uint8Array(array)], {type: 'image/jpg', name: "Sample"});
} // img.onload
}
// Load files into file reader
reader.readAsDataURL(file);
}
</script>
Giving you a few other tips along the way... filereader is not the preferred way. and the way you build your blob afterwards is no good, use canvas#toBlob directly instead.
function ClientSideResize () {
// var uniq = 'id' + Date.now() // never used
var filesToUpload = document.getElementById('input').files
var file = filesToUpload[0]
// Create an image
var img = new Image
img.onload = () => {
const MAX_WIDTH = 200
const MAX_HEIGHT = 400
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
var width = img.width
var height = img.height
// figure out new width and hight while keeping proportionally
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
}
}
// set diminsion
canvas.width = width
canvas.height = height
// draw resized image
ctx.drawImage(img, 0, 0, width, height)
// get it as a blob
canvas.toBlob(blob => {
// Do something with blob
// let file = new File([blob], 'filename.png', {type: blob.type})
let iframe = document.querySelector('iframe')
iframe.contentWindow.postMessage(blob, '*')
}, 'image/jpeg', 100)
} // img.onload
img.src = URL.createObjectURL(file)
}
// on iframe
window.onmessage = event => {
console.log(event) // will contain your blob object
}
I'm trying to resize big/large images on client and upload the smaller image. This works perfectly with one or ten images. But i want to upload mybe 50+ images. This will work but it slows down my cpu and memory. The code for the resized images is this:
var MAX_WIDTH = 1920;
var MAX_HEIGHT = 1920;
var loaded = 0;
var URL = window.URL || window.webkitURL;
function loadImage(file) {
var mime = file.type;
var src = URL.createObjectURL(file);
var img = new Image();
img.onload = (function (image) {
return function () {
var newHeight = MAX_WIDTH;
var newWidth = MAX_HEIGHT;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(image, 0, 0, this.width, this.height, 0, 0, newWidth, newHeight);
URL.revokeObjectURL(this.src);
var dataURI = canvas.toDataURL(mime);
var blob = dataURLToBlob(dataURI);
imagesToUpload.push(blob);
loaded++;
if (loaded < checkedFiles.length) {
loadImage(checkedFiles[loaded]);
} else {
//DO UPLOAD
input.value = "";
}
}
})(img);
img.src = src;
image = null;
}
loadImage(checkedFiles[0]);
While resizing and uploading, i want to show a loading animation. And this anmiation is very slow.
I think the problem is while resizing the image on the canvas-object, but i have no idea to solve this issue.
The MAX-PICTURE-WITH is 1920px and the MAX-PICTURE-HEIGHT is 1920px.
It would be great if someone can give me a clue?
I'm resizing the image before upload it to the server using HTML5 Canvas.
Also I use Angular's module ng-file-upload.
Stack on getting dataUrl of resized image. Console returns data:,
What could be the problem here?
HTML
<input type="file" ngf-select ng-model="files">
<img ngf-src="files[0]">
JS
$scope.upload = function (files) {
if (files && files.length==1) {
var file = files[0];
var img = document.createElement("img");
var canvas = document.createElement("canvas");
var reader = new FileReader();
reader.onload = function(e) {img.src = e.target.result};
reader.readAsDataURL(file);
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 200;
var MAX_HEIGHT = 150;
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);
var dataurl = canvas.toDataURL("image/png");
console.log( dataurl );
...
He had the same problem and solve it with:
$scope.upload = function (files) {
if (files && files.length==1) {
var file = files[0];
var URL = window.URL || window.webkitURL;
var srcTmp = URL.createObjectURL(file);
var img = new Image();
img.onload = function() {
alert(this.width + 'x' + this.height);
}
img.src = srcTmp;