I am trying to resize bulky image to reduce size image. For this i have implemented following code.
<html>
<head>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
</head>
<body>
<input type='file' id="fileUpload" />
<canvas id="canvas" width="450" height="300"></canvas>
</body>
<script type="text/javascript">
function el(id) {
return document.getElementById(id);
}
var canvas = el("canvas");
var context = canvas.getContext("2d");
function readImage() {
if ( this.files && this.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
var img = new Image();
img.addEventListener("load", function() {
context.drawImage(img, 0, 0);
var MAX_WIDTH = 450;
var MAX_HEIGHT = 300;
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.mozImageSmoothingEnabled = true;
ctx.webkitImageSmoothingEnabled = true;
ctx.msImageSmoothingEnabled = true;
ctx.imageSmoothingEnabled = true;
ctx.drawImage(img, 0, 0, width, height);
});
img.src = e.target.result;
};
FR.readAsDataURL( this.files[0] );
} else {
alert("error");
return false;
}
var canvas = el("canvas");
var dataURL = canvas.toDataURL();
$.ajax({
type: "POST",
url: "http://localhost/newtry/lipak.php",
data: {
imgBase64: dataURL
}
}).done(function(o) {
console.log('saved');
});
}
el("fileUpload").addEventListener("change",readImage);
</script>
</html>
and in another php file i have a code to retrieve this code as follows
file_put_contents('photo.png', base64_decode(substr($_POST['imgBase64'], strpos($_POST['imgBase64'], ",")+1)));
but when i am uploading my first image its not getting saved. but after uploading another image first image got saved .. similarly second, third and so on.
So how can i retrieve an image on first attempt?
Vinay please call ajax in load function
function readImage() {
if ( this.files && this.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
var img = new Image();
img.addEventListener("load", function() {
context.drawImage(img, 0, 0);
var MAX_WIDTH = 450;
var MAX_HEIGHT = 300;
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.mozImageSmoothingEnabled = true;
ctx.webkitImageSmoothingEnabled = true;
ctx.msImageSmoothingEnabled = true;
ctx.imageSmoothingEnabled = true;
ctx.drawImage(img, 0, 0, width, height);
$.ajax({
type: "POST",
url: "http://localhost/newtry/lipak.php",
data: {
imgBase64: dataURL
}
}).done(function(o) {
console.log('saved');
});
});
img.src = e.target.result;
};
FR.readAsDataURL( this.files[0] );
} else {
alert("error");
return false;
}
var canvas = el("canvas");
var dataURL = canvas.toDataURL();
}
el("fileUpload").addEventListener("change",readImage);
</script>
Related
I have a function for resizing image when using this function I get empty string "", and reader.onload doesn't run, I want to run reader.onload at first, how can I fix this?
function Ds_JsImgResize( Filereq,MaxWidth , MaxHeight) {
if (Filereq.files.length != 0) {
AjaxBegin();
var file = Filereq.files[0];
var file_type = file.type;
if (file_type && file_type.substr(0, 5) == "image") {
var img = document.createElement("img");
var reader = new FileReader();
reader.onload = function (e)
{
debugger
img.src = e.target.result;
img.onload = function (imageEvent) {
var MAX_WIDTH = MaxWidth;//300;
var MAX_HEIGHT = MaxHeight;//300;
var width = img.naturalWidth;
var height = img.naturalHeight;
//resize the image if it higher than MAX_WIDTH or MAX_HEIGHT
if ((width > MAX_WIDTH) || (height > MAX_HEIGHT)) {
if ((width / height) > (MAX_WIDTH / MAX_HEIGHT)) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
else {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
//following two lines saves the image
var image = canvas.toDataURL("image/png");
// $('#PicPic').attr('src', image);
AjaxComplete();
return image;
// DsformData.append('PicV', image);
//Ds_IM_JsCallAjax_async(DsformData, 'LC_Prof_IM_JsSabt_AfterAjax');
// return 0;
}
};
};
AjaxComplete();
reader.readAsDataURL(file);
}
AjaxComplete();
return "";
}
AjaxComplete();
return "";
}
this is my first post, so, please, be nice
removing these lines.
<!--This 1x1 picture size workaround is a real flower-->
<img src="" id="preview" width="1" height="1">
causes the below script to malfunction. Can someone explain what I'm doing wrong?
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#imageFile').change(function(evt) {
var files = evt.target.files;
var file = files[0];
//reader.onprogess = function(event) {
// document.getElementById('progressbar').innerHTML = "Progressbar";
// sleep
// };
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById('preview').src = e.target.result;
document.getElementById('status').innerHTML = "Upload succesful";
ResizeImage();
};
reader.readAsDataURL(file);
}
});
});
function ResizeImage() {
if (window.File && window.FileReader && window.FileList && window.Blob) {
var filesToUpload = document.getElementById('imageFile').files;
var file = filesToUpload[0];
if (file) {
var reader = new FileReader();
// Set the image once loaded into file reader
reader.onload = function(e) {
var img = document.createElement("img");
img.src = e.target.result;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 400;
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();
document.getElementById('output').src = dataurl;
}
reader.readAsDataURL(file);
}
} else {
alert('Not working so well in this browser');
}
}
</script>
</head>
<input id="imageFile" name="imageFile" type="file" class="imageFile" accept="image/gif, image/jpeg, image/png"/>
<br/>
<!--This 1x1 picture size workaround is a real flower-->
<img src="" id="preview" width="1" height="1">
<p id="status">status</p>
<img src="" id="output">
Im trying to reduce the size of the image after reading at client side, the javascript code is as below, I'm getting two issues here
1) The image preview is not showing up on the img id "img-upload"
2) The file that is being submitted via form submission "reader.readAsDataURL(input.files[0])" is not the reduced size one.
I did try changing code to move the reader inside the image onload and then pass e.target.files[0] but that didn't work either.
Pls advise how I can resize and then send it via form submission to my backend.
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img-upload').attr('src', e.target.result);
img.onload = function () {
var MAX_WIDTH = 100;
var MAX_HEIGHT = 100;
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;
}
}
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(this, 0, 0, width, height);
img.src = e.target.result;
$('#img-upload').append(img);
}
}
reader.readAsDataURL(input.files[0]);
}
}
Your code is creating an infinite call to img.onload
because of this
img.src = e.target.result; statement inside onload.
Beside this you are not reading the resized image from the canvas.
You can do this the following way
canvas.toDataURL('image/png');
SNIPPET
var img = $('#img-upload')[0];
var show = $('#show')[0];
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
debugger;
$('#img-upload').attr('src', e.target.result);
img.onload = function() {
var MAX_WIDTH = 100;
var MAX_HEIGHT = 100;
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;
}
}
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(this, 0, 0, width, height);
//Causing Infinite Loop in your code
//img.src = e.target.result;
// Get dataURL of resized image from canvas
show.src = canvas.toDataURL('image/png');
}
}
reader.readAsDataURL(input.files[0]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" onchange="readURL(this)">
<img id="img-upload">
<img id="show">
I'm trying hard to accomplish and understand the following 'monstercode' that I wrote. Basically, this function should fire when the File input dialog (HTML) was fired. But the code goes well only a few lines. It loads the image, and then in the first alert() it shows me the base64 of the original image, but then, later in the code, when the actual image should be loaded in a canvas, it returns (in another alert()) height 0, probably meaning that the image wasn't loaded correctly or at all.
The HTML input form (simplified) looks like this:
<input type='File' accept='image/*' onChange='changeBtn(this);' />
And the function below:
function changeBtn(elem) {
selfile = document.getElementById(elem.id);
if ('files' in selfile) {
var file = selfile.files[0];
if ('name' in file) {
str1 = file.name;
}
if ('size' in file) {
str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)';
}
document.getElementById("label_" + elem.id).innerHTML = str1;
var FR= new FileReader();
var img = document.createElement("img");
FR.onload = function(e) {
img.src = e.target.result;
alert(e.target.result); // Returns B64 of the original image
};
FR.readAsDataURL(file);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;
alert(height); // Returns 0
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");
alert(dataurl); // Returns only "data; " and nothing more
}
}
Thanks in advance for any help. Seems quite simple, but I don't get it. I rewrote the code at least 3 times, but I get always the same result.
Figured it out!
I was calling FR.readAsDataURL(file); before loading the image into it, leading it to load an undefined file.
If we look at following code that has failed:
var FR= new FileReader();
var img = document.createElement("img");
FR.onload = function(e) {
img.src = e.target.result;
alert(e.target.result); // Returns B64 of the original image
};
FR.readAsDataURL(file);
we now know why. First var FR= new FileReader(); is called, then FR.readAsDataURL(file); and then, at last, when the onload fires: img.src = e.target.result;. That's the wrong order. The right order is:
function changeBtn(elem) {
selfile = document.getElementById(elem.id);
if ('files' in selfile) {
var file = selfile.files[0];
if ('name' in file) {
str1 = file.name;
}
if ('size' in file) {
str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)';
}
document.getElementById("label_" + elem.id).innerHTML = str1;
var FR= new FileReader();
FR.readAsDataURL(file);
var img = document.createElement("img");
FR.onload = function(e) {
img.src = e.target.result;
alert(e.target.result);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;
alert(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");
alert(dataurl);
};
}
}
I have this code that resize the image and I want it to upload after resizing photo and submit the form using Ajax. I tried doing it but, it doesn't seems to resize my photo. I'm new to Javascript, please guide me. Below is my code:-
<form id="imgLocal" name="imgLocal" accept-charset="utf-8" enctype="multipart/form-data">
<input type="file" name="receipt" id="receipt" accept="images/*" onchange="handleFiles();" />
</form>
// Form validation above
submitHandler:function(form) {
var formData = new FormData(form);
$.ajax({
type: 'POST',
url: 'a/imgUpload',
dataType: 'json',
data: formData,
cache: false,
contentType: false,
processData: false
}).success(function(data){
show('loading', false);
alert('success');
}else {
alert('error');
}
function handleFiles()
{
var filesToUpload = document.getElementById('receipt').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;
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 = 300;
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");
$('#receipt').attr('value', dataurl);
}
reader.readAsDataURL(file);
}
}
You cannot set a file input with new data, the user has to choose a file for security reasons.
In order to upload a generated image you can upload the data url and decode the base64 string back to binary format and save it server side. Or you can get the image from the canvas as a blob and then attach it to your FormData object.
instead of calling toDataURL you can call toBlob to get a blob object.
canvas.toBlob(function(imgBlob){
formData.append("receipt",imgBlob,"filenameForImage.png");
},'image/png');
Note that the toBlob method is not yet fully supported, but the MDN reference does give a polyfill that can be used:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
if (!HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, toBlob, {
value: function (callback, type, quality) {
var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),
len = binStr.length,
arr = new Uint8Array(len);
for (var i=0; i<len; i++ ) {
arr[i] = binStr.charCodeAt(i);
}
callback( new Blob( [arr], {type: type || 'image/png'} ) );
}
});
}
You can try this
html
<form id="imgLocal" name="imgLocal" accept-charset="utf-8" enctype="multipart/form-data">
<input type="file" name="receipt" id="receipt" accept="images/*" onchange="handleFiles();" />
</form>
<script>
function handleFiles()
{
var image= document.getElementById('receipt');
var file = image.files[0];
var img = document.createElement("img");
var reader = new FileReader();
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 = 400;
var MAX_HEIGHT = 300;
var width = this.width;
var height = this.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");
upload(dataurl);
};
image.onerror= function() {
alert('Invalid file type: '+ file.type);
};
}
reader.readAsDataURL(file);
}
}
function upload(file) {
var form = new FormData();
form.append('image', file);
$.ajax({
url: 'server.php',
data: form,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
}
</script>
Server side :
<?php
$filename = "image_".uniqid().".png";
$dest = __DIR__.$filename;
$imgData = str_replace(' ','+',$_POST['image']);
$imgData = substr($imgData,strpos($imgData,",")+1);
$imgData = base64_decode($imgData);
$file = fopen($dest, 'w');
fwrite($file, $imgData);
fclose($file);
?>
Check my blog