Image resize before upload without preview javascript - javascript

I want to avoid uploading big/heavy image files.
I prefer HTML5 FileAPI library for this job.
All other functionality is added (upload, re-order, etc.), so I only need the image-resize function.
CASE:
On the page there is an input for multiple files.
On input change event (when adding files), resize the entered images/files and append them to FormData(), then send the FormData() to PHP script via ajax.
EXAMPLE:
$('input').on('change',function(){
var formData = resizeImages(this.files[0]);
uploadResizedImages(formData);
});
function resizeImages(files){
formData = new FormData();
//For each image, resize it and append to formData
//resize file part missing....
formData.append('files[]',this);//Appending to formData (this = currently iterated file)
return formData;//Return the formData with resized images
}
Anyone?
Thanks

In my experience you cannot manipulate the image on the client side then upload the manipulated image in tact via a file input in a form.
The way I have done what you are trying to do in the past involves a few steps.
Select image using a file input
Read the file as a dataURL
Use canvas to manipulate the image as needed
Export the new image as a dataUrl
Use ajax to upload the image to the server as a dataURL
Use server side functions to convert the dataUrl to an image and store
https://jsfiddle.net/0hmhumL1/
function resizeInCanvas(img){
///////// 3-3 manipulate image
var perferedWidth = 2700;
var ratio = perferedWidth / img.width;
var canvas = $("<canvas>")[0];
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0,0,canvas.width, canvas.height);
//////////4. export as dataUrl
return canvas.toDataURL();
}
When uploading as a dataUrl you increase the size (bandwidth required) of the manipulated image by about 20% so you may not see the savings you are looking for unless you are changing the image size considerably.

Related

JS-Convert an Image object to a jpeg file

So, I have a user input which serve to upload pictures. This is a simple example:
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
console.log (img);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
<input type="file" onchange="handleImage(event)"><br>
As you can see, I display an Image () on the console. I want to convert this Image into a jpg file.
I understood how to get the pixels of the picture but it's completely crazy to send it to a server: It's to large!
I also tried to access to the jpg file stored in the computer but I do not achieve to anything.
The only way I found is to send it with a form like this:
<form action="anything.php" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
</form>
And in PHP:
$_FILES["fileToUpload"]["tmp_name"]
Why not with JS?
My final goal is to send the jpg file with AJAX.
Tell me if you have some questions.
The simplest way is to use a canvas element and then invoke a download action allowing the user to select where to save the image.
You mention that the image is large, but not how much - be aware that with canvas you will also run into restrictions when the image source starts to touch around the 8k area in pixel size.
A simplified example (IE will require a polyfill for toBlob()).:
Load image source via input
Use File blob directly as image source via URL.createObjectURL()
When loaded, create a temporary canvas, set canvas size = image size and draw in image
Use toBlob() (more efficient on memory and performance and require no transcoding to/from Base64) to obtain a Blob.
We'll convert the Blob to File (a subset object and it will reference the same memory) so we can also give a filename as well as (important!) a binary mime-type.
Since the mime-type for the final step is binary the browser will invoke a Save as dialog.
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
c.toBlob(function(blob) {
var file = new File([blob], "MyJPEG.jpg", {type: "application/octet-stream"});
window.location = URL.createObjectURL(file);
}, "image/jpeg", 0.75); // mime=JPEG, quality=0.75
}
// NOTE: toBlob() is not supported in IE, use a polyfill for IE.
<label>Select image to convert: <input type=file></label>
Update: If you just are after a string (base-64 encoded) version of the newly created JPEG simply use toDataURL() instead of toBlob():
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
var jpeg = c.toDataURL("image/jpeg", 0.75); // mime=JPEG, quality=0.75
console.log(jpeg.length)
}
<label>Select image to convert: <input type=file></label>
JavaScript on the client side can not save files.
You have multiple options:
Render the image on an <canvas> element. This way it can be saved with right click -> save image
Inset the image as <img> element. This way it can be saved with right click -> save image
Send the image data as base64 string to the server. Do the processing there
Use a server side language like PHP or Node.js to save the file
Long story short, you have to use some server side logic to save the file on disk

How to select file, fix orientation, and add to canvas

My site allows users to upload their own photos. I've learned that this is trickier than first expected and although I can get each of the components working individually I'm not successfully getting them to produce the outcome I need when combining them. I believe the issue is my lack of understanding around the outputs of the functions i'm using.
I think what I need to do is:
Let the user choose the file to upload
Check / fix the orientation
Display the image in a canvas
Convert the canvas to base64 (to upload to Firebase)
Upload the item
Let the user choose the file to upload
$(document).on('change','#fileUpload',function(e) {
correctImageOrientation(e);
});
Check / fix the image orientation
I'm using image-load (link) for my orientation changes.
function correctImageOrientation(e) {
loadImage(
e.target.files[0],
function (img) {
// document.body.appendChild(img); // Note: this successfully appends the image in the correct orientation to the body - but I need to do this to a canvas to I call:
addImageToCanvas(img);
},
{
orientation: true
}
);
Display the image in a canvas
This part fails. If I pass in the selected file using e.target.files[0] and create an objectURL then it works. This is why I think the img i'm passing in needs to be read / displayed on the canvas differently.
function addImageToCanvas(img) {
img.onload = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, 300, 300);
console.log("Ending img.onload"); // This is never reached
}
}
I can then successfully convert the file to base64 and upload to Firebase.
I think there must be an easier way to achieve what I want which is for people to upload an image, for the orientation to be correct, and for this to be stored online.
EDIT: To store the image in firebase I am using this to convert the image back to a blob.
I have replaced addImageToCanvas with the function below which was taken then modified from David Walsh's site. Because I'm passing in an image I needed to convert this to a canvas.
function convertImageToCanvas(image) {
var canvas = document.getElementById("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
}

Uploading files directly to Amazon S3 from Ember JS

I am using ember uploader in order to upload files directly to Amazon S3 from my client once I have signed the image upload on the server as described here
Now what I am trying to do is resize the image to create a thumbnail before uploading to Amazon S3. This way I'll have two images to upload to Amazon S3. One will be the original image and the other will be the thumbnail created.
At the moment I am using a HTML 5 canvas in order to resize the image:
var MAX_HEIGHT = 300;
function render(src){
var image = new Image();
image.onload = function(){
var canvas = document.getElementById("myCanvas");
if(image.height > MAX_HEIGHT) {
image.width *= MAX_HEIGHT / image.height;
image.height = MAX_HEIGHT;
}
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
};
image.src = src;
}
I am able to resize the image in the HTML 5 canvas. The problem I am facing is that I am battling to then get the image back into a File Object for the Ember Uploader to sign and send over to Amazon S3.
This is the code that handles the actual upload:
if (!Ember.isEmpty(files)) {
uploader.upload(files[0]); // Uploader will send a sign request then upload to S3
}
As you can see, the first item of the FileList array is being uploaded. I would like to be able to append the canvas' thumbnail image to this FileList in order to iterate over the FileList and then sign and upload both images to Amazon S3.
I know that a canvas can be converted to a data url using canvas.toDataURL but is it possible to covert a canvas to a File Object or should I do the resize and upload in a different way?
Thanks!

Javascript: loading image from bytearray

In Javascript you have the ByteArray type and some views on it as described here:
https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays
is it possible to store image data in such bytes and if yes, how can i display such an image? png or jpg?
Yes, you can store an image using the typed arrays.
Im not sure what you want actually.
If you want to create an HTMLImageElement from a ByteArray, you can do something similar as cited in here and here.
If you want to get the bytes from an Image, that would be trickier. You can draw the ImageElement to HTML canvas, and them get the URI back using toDataURL.
I just tried to get the data using canvas and it worked.
var myCanvas = document.getElementById('my_canvas_id');
var ctx = myCanvas.getContext('2d');
var img = new Image;
img.onload = function(){
myCanvas.width = img.width;
myCanvas.height = img.height;
ctx.drawImage(img,0,0); // Or at whatever offset you like
alert(myCanvas.toDataURL());
};
img.src = "logo4w.png";
Although, the method toDataURL() do not allow you to perform this operation if the image you draw on canvas comes from outside the website domain.

is there any function like getimagesize() php in javascript?

I have create upload file , but I have stack when I want to validation that content is image or not, because if validate extension only we can manipulate with fake content and valid extension.
is there function similar getimagesize() php in javascript?
In some of the more modern browsers you can load an image into a canvas context (this doesn't actually have to be displayed on the page) and get the dimensions from that.
I did something like this in a CMS I built to allow the image to be scanned for certain colours without it having to be uploaded to a server first:
$('section.content form input[name=image]').change(function(){
file = this.files[0];
if(file.type.match(/image.*/))
{
var img = document.createElement('img');
// add this into an onload, as it takes time (albeit very little) to load the image into the DOM object
img.onload = function(){
canv = document.getElementById('product_image');
if(!canv || !canv.getContext)
return; // problem getting the canvas element
// get the canvas context that we'll be using and the width of the canvas & image
var ctx = canv.getContext('2d');
var width = img.width;
var height = img.height;
};
// put the file into the img object, triggering the img onload handler above
var reader = new FileReader();
reader.onload = function(e) {img.src = e.target.result};
reader.readAsDataURL(file);
}
});

Categories

Resources