image.onError on jquery-mobile while uploading images - javascript

I am using PhoneGap to run my JQuery Mobile Hybrid App.
I am following this tutorial in order to upload image from my Device (Samsung Note4, Android 6.0.1) to the canvas, I have tried with different types of images but I am always getting the execution result of the image.onError.
What could be the reason of getting the image.onError execution?
Here is the code from the tutorial:
function processFile(dataURL, fileType) {
var maxWidth = 800;
var maxHeight = 800;
var image = new Image();
image.src = dataURL;
image.onload = function () {
var width = image.width;
var height = image.height;
var shouldResize = (width > maxWidth) || (height > maxHeight);
if (!shouldResize) {
sendFile(dataURL);
return;
}
var newWidth;
var newHeight;
if (width > height) {
newHeight = height * (maxWidth / width);
newWidth = maxWidth;
} else {
newWidth = width * (maxHeight / height);
newHeight = maxHeight;
}
var canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
var context = canvas.getContext('2d');
context.drawImage(this, 0, 0, newWidth, newHeight);
dataURL = canvas.toDataURL(fileType);
sendFile(dataURL);
};
image.onerror = function () {
alert('There was an error processing your file!');
};
}

Related

problem with reader.onload for resizing image

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 "";
}

Reducing size of the image at Client Side in javascript before form submission

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">

JS multiselect images and draw them into canvas - sometimes canvas blank or same image drawn

I am using JS and a multi select field.
A user can select multiple images from a folder and then each image should be drawn into a canvas. Each image has a predefined canvas and a predefined input field where then the decoded base64 dataurl is placed in.
The multiselect field:
<input id="bild" multiple="" name="bild" type="file">
In my example there are 3 different canvas elements and 3 different dataurl input fields:
$( "input#bild" ).change(function() {
console.log("multiple");
// from an input element
var filesToUpload = this.files;
//console.log(filesToUpload);
if(typeof this.files[0] !== "undefined") {
console.log("multiple-1");
var img = document.createElement("img");
img.src = window.URL.createObjectURL(this.files[0]);
$( img ).load(function() {
console.log("multiple-1-loaded");
canvas = $("#uploading_canvas_image_1").get(0);
var MAX_WIDTH = 550;
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);
var dataurl = canvas.toDataURL("image/jpg");
$( "#dataurl_image_1" ).val(dataurl);
});
}
if(typeof this.files[1] !== "undefined") {
console.log("multiple-2");
var img = document.createElement("img");
img.src = window.URL.createObjectURL(this.files[1]);
$( img ).load(function() {
console.log("multiple-2-loaded");
canvas = $("#uploading_canvas_image_2").get(0);
var MAX_WIDTH = 550;
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);
var dataurl = canvas.toDataURL("image/jpg");
$( "#dataurl_image_2" ).val(dataurl);
});
}
if(typeof this.files[2] !== "undefined") {
console.log("multiple-3");
var img = document.createElement("img");
img.src = window.URL.createObjectURL(this.files[2]);
$( img ).load(function() {
console.log("multiple-3-loaded");
canvas = $("#uploading_canvas_image_3").get(0);
var MAX_WIDTH = 550;
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);
var dataurl = canvas.toDataURL("image/jpg");
$( "#dataurl_image_3" ).val(dataurl);
});
}
For each image I am checking if it is really there and not undefined. Then it is drawn into the canvas and the corresponding field for dataurl is populated with the dataurl.
The Problem is:
I do not get any errors.
The behaviour is different with different sets of images but its always the same with the same set. For example: I am marking 3 different images in the folder which I want to upload, but always all 3 canvas show the same image (3rd) one also all 3 dataurls are the same.
Sometimes some canvas are blank.
Sometimes it works
It seems like a general problem, but I havent managed to locate why this happens. My guess is it maybe has something to do with the onload function for the image and that the dataurl is created in the same steps. The dataurl itself is insanly long. I am looking at this atm. Maybe someone here has an idea.
I found the issue. The img was causing these problems. Because I always used the same img, eventhough it is in the if condition block. It seems that the function itself is stronger then the if condition?
I had to create a new img variable for every image selected, which means I needed this for image 1:
var img1 = document.createElement("img");
img1.src = window.URL.createObjectURL(this.files[0]);
$( img1 ).load(function() {
//...
ctx.drawImage(img1, 0, 0, width, height);
});
For image 2:
var img2 = document.createElement("img");
img2.src = window.URL.createObjectURL(this.files[1]);
$( img2 ).load(function() {
//...
ctx.drawImage(img2, 0, 0, width, height);
});
For image 3:
var img3 = document.createElement("img");
img3.src = window.URL.createObjectURL(this.files[2]);
$( img3 ).load(function() {
//...
ctx.drawImage(img3, 0, 0, width, height);
});

Show resized Base64 output of an image

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);
};
}
}

Canvas draw new image from daturl

I'm using the function below to resize and image using canvas
var img = new Image();
img.src = reader.result;
img.onload = function() {
var max_width = 800;
var max_height = 800;
var tempW = img.width;
var tempH = img.height;
var aspect_ratio = 1;
if (tempW > tempH) {
if (tempH > max_height){
var aspect_ratio = tempH / max_height
}
} else {
if (tempW > max_width){
var aspect_ratio = tempW / max_width
}
}
tempH = tempH / aspect_ratio;
tempW = tempW / aspect_ratio;
var canvas = document.createElement('canvas')
canvas.id = "uploadedcanvas";
canvas.width = tempW;
canvas.height = tempH;
var ctx = canvas.getContext("2d");
ctx.fillStyle="#FFFFFF";
ctx.fillRect(0,0,tempW,tempH);
ctx.drawImage(this, 0, 0, tempW, tempH);
var dataURL = canvas.toDataURL("image/jpeg");
createsecondimage(dataURL,tempW,tempH,max_width,max_height,canvas)
}
This is able to resize an image from taken from file reader. I would like to create a second image in the same canvas using the dataURL as the image source but this it does not seem to work this is what I'm doing
function createsecondimage(dataURL,tempW,tempH,max_width,max_height,canvas){
var copy = document.createElement('canvas');
copy.width = max_width;
copy.height = max_height;
var copyctx = copy.getContext("2d");
var sx = (tempW - max_width) / 2
var sy = (tempH - max_height) /2
copyctx.fillStyle="#FFFFFF";
copyctx.fillRect(0,0,max_width,max_height);
var imgcopy = new Image();
imgcopy.src = dataURL;
imgcopy.onload = function() {
copyctx.drawImage(imgcopy, sx, sy, 800, 800,0, 0, 800, 800);
var dataURL_ = copy.toDataURL("image/jpeg");
}
However datURL_ appears to be empty. I'm not sure why this is the case. Ideally I would want to create a new image using the image that was just resized.
You can do the following two changes and it should work:
set imgcpy.src after onload.
Use copyctx.drawImage(this, ...) instead of imgcopy.
This way you are making sure decoding and setting of image is not completed before onload is called, and this will have a valid reference to the image being decoded.

Categories

Resources