So I have a website (using AngularJS) that lets users upload files via tag
<input type="file" ng-model="image" id="trigger" onchange="angular.element(this).scope().setFile(this)" accept="image/*">
When I handle the upload in the controller the image gets stored as a File object. This is my method that saves the file and also sets variables to preview the image
$scope.setFile = function (element) {
$scope.image = element.files[0]; // This is my image as a File
var reader = new FileReader();
//This is for previewing the image
reader.onload = function (event) {
$scope.image_source = event.target.result;
$scope.$apply();
}
reader.readAsDataURL(element.files[0]);
}
Now I am trying to compress the image using J-I-C library found here: https://github.com/brunobar79/J-I-C/blob/master/src/JIC.js
But this library accepts an image object as its parameter and returns it as a compressed image object. I can't seem to find a way to convert my $scope.image File object into an Image object. How would I go about doing this?
I would also need to convert the compressed image object back into a File so I can upload it to my Azure storage.
You just need to create an Image instance, and set it's src to your data url. Then pass it to JIC:
var img = new Image();
img.src = $scope.image_source;
jic.compress(img,...)
It then just uses a canvas element to manipulate the image, generate a new data url, and creates a new Image instance, setting its src to the data url. So when you get the compressed image back just take the src and use atob to decode the base64 encoded data back into binary and create a Blob. You can use Blob in most places that you would use File, for instance like uploading through ajax.
var newImg = jic.compress(oldImg,...);
//replace 'image/png' with the proper image mime type
var base64data = newImg.src.replace("data:image/png;base64,","");
var bs = atob(base64data);
var buffer = new ArrayBuffer(bs.length);
var ba = new Uint8Array(buffer);
for (var i = 0; i < bs.length; i++) {
ba[i] = bs.charCodeAt(i);
}
var blob = new Blob([ba],{type:"image/png"});
//now use blob like you would any other File object
Related
I've got a FileReader that lets the user upload a file (image) to my site.
Here's the code that does the reading:
$("input[type='file']").change(function(e) {
var buttonClicked = $(this);
for (var i = 0; i < e.originalEvent.srcElement.files.length; i++) {
var file = e.originalEvent.srcElement.files[i];
var img = document.createElement("img");
var reader = new FileReader();
reader.onloadend = function() {
img.src = reader.result;
console.log(reader.result);
}
reader.readAsDataURL(file);
}
});
All is good and well, until I tried to print out my result. I used this file for example:
When I console.log() the result, it spits out over 95000 characters.
This image in particular is around the same size as the images I will be accepting into my site.
I was hoping to store these images in a database as well, and so I'm wondering how this is going to be possible with image sources that are so extremely long. Is there a way to shorten this or get the image path a different way?
I'm moreso curious as to why they're so long, but if someone has a tip to store these (100s per user, 500+ users) that'd be nice as well!
Thanks-
Store the Files as ... Files.
There are very little use cases where you need the toDataURL() method of the FileReader, so every time you use it, you should ask yourself why you need it.
In your case :
To display the image in the page. Well don't use a FileReader for this, instead create a direct pointer to the file in the form of an url, available only to this session. This can be achieved with the URL.createObjectURL(File_orBlob) method.
To store this image on your server. Don't store a ~37% bigger base64 version, send and store directly the file as a file (multipart). This can be achieved easily with the FormData API.
inp.onchange = function(){
var file = this.files[0];
if(file.type.indexOf('image/') !== 0){
console.warn('not an image');
}
var img = new Image();
img.src = URL.createObjectURL(file);
// this is not needed in this case but still a good habit
img.onload = function(){
URL.revokeObjectURL(this.src);
};
document.body.appendChild(img);
}
// not active but to give you da codez
function sendToServer(){
var file = inp.files[0];
var form = new FormData();
// here 'image' is the parameter name where you'll retrieve the file from in the request
form.append('image', file);
form.append('otherInfo', 'some other infos');
var xhr = new XMLHttpRequest();
xhr.open('post', 'yourServer/uploadPage')
xhr.onload = function(){
console.log('saved');
};
xhr.send(form);
}
<input type="file" id="inp">
And if you need PHP code to retrieve the File form this request :
if ( isset( $_FILES["image"] ) ){
$dir = 'some/dir/';
$blob = file_get_contents($_FILES["image"]['tmp_name']);
file_put_contents($dir.$_FILES["image"]["name"], $blob);
}
You're going to want to upload the files to a server of some sort (a backend that is serving up your javascript), and then from there you'll want to
Validate the file
Store the file on a physical server (or the cloud) somewhere
Add an entry in a database that relates the file path or ID of that upload to the user who just uploaded it (so you can retrieve it later if needed)
So basically, you don't store the image in your database, you store it on a file share/cloud host somewhere, and instead you only store what is needed to download/retrieve the image later.
I'm using the management API to get all my installed apps and extensions. I want to send this information to server.
Every app/extension has an icon array, that has size and url.
The url is something like chrome://extension-icon/gmgpodcgeocidkeclglljo88jp9kclhhmmdacfo/32/0. I want to send it to my server in base64.
What I'm trying to do is something like:
var reader = new FileReader();
reader.onloadend = function() {
result = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
result = "";
}
Where file is a File object of the icon url. But I cannot find how to create an File object with this url format.
I've tried:
var fileUrlArray = ["chrome://extension-icon/gmgpodcgeocidkeclglljo88jp9kclhhmmdacfo/32/0"];
var file = new File(fileUrlArray, 'icon.png');
And as a result I got an absolutely wrong base64 string.
Any ideas about how to do it?
Thanks.
I'm developing an app and trying to upload an image in base64 to my server. Testing the code via web it works perfectly! And when I convert the image in base64 to File, it returns me the following object:
But when I try to make the same thing in my mobile app running on an Android device, the same code creates to me the following File object:
What is happening? I call the function to convert my base64 image to File as this:
var blob = new Blob([photoBase64], {type: 'image/png'});
var filePhoto = new File([blob], "employeePhoto.png");
In first image (which worked) I was running on web browser.
In second image (not worked) I was running on Android app.
It is the same code...
It appears that File constructor have different behavior in web browser and Android app. I am not understanding this. Passing the parameters to File constructor in the same order create different File objects (as the described on images).
If you are trying to convert base64 to File, you can utilize part of canvas.toBlob() polyfill
var base64 = "data:image/png,base64,"; // data URI
var binStr = atob(base64.split(",")[1]),
len = binStr.length,
arr = new Uint8Array(len);
for (var i = 0; i < len; i++) {
arr[i] = binStr.charCodeAt(i);
}
var file = new File([arr], "image");
var img = new Image;
img.onload = function() {
document.body.appendChild(this);
URL.revokeObjectURL(url);
}
var url = URL.createObjectURL(file);
img.src = url;
I have created an app in sencha touch cordova, and in my app I have a functionality to download PDFs.
I have successfully downloaded a pdf file, but now I want to convert the PDF into a base64 string using JavaScript.
Can anybody tell me how to do it?
See if your JavaScript environment has the "atob" and "btoa" functions available:
var encodedData = window.btoa("Hello, world"); // encode a string
var decodedData = window.atob(encodedData); // decode the string
These convert a string to and from Base64 encoding.
Trying using the logic below.
<input id="inputFile" type="file" onchange="convertToBase64();" />
function convertToBase64(){
//Read File
var selectedFile = document.getElementById("inputFile").files;
//Check File is not Empty
if (selectedFile.length > 0) {
// Select the very first file from list
var fileToLoad = selectedFile[0];
// FileReader function for read the file.
var fileReader = new FileReader();
var base64;
// Onload of file read the file content
fileReader.onload = function(fileLoadedEvent) {
base64 = fileLoadedEvent.target.result;
// Print data in console
console.log(base64);
};
// Convert data to base64
fileReader.readAsDataURL(fileToLoad);
}
}
Note : This snippet was taken from stackoverflow, but I dont remember the link :(
I have a geotiff file that is being converted to a base64string upon being selected. The encoded file is then uploaded to an ASP.NET web service and then decoded and saved with a .tiff extension. The problem is that the metadata within the file is significantly altered from the original file.
JavaScript
var fr = new FileReader();
fr.onloadend = function () {
var base64string = fr.result;
var imgStr = base64string.split("base64,")[1];
App.instance.client.area.uploadMap(imgStr);
};
fr.readAsDataURL(value.rawFile);
C#/ASP.NET Web API:
byte[] imageBytes = Convert.FromBase64String(mapImage);
MemoryStream ms = new MemoryStream(imageBytes);
Image img = Image.FromStream(ms);
I'm then extrating the metadata uploaded image with the GDAL library. The image looks fine, but the metadata contained within the file is completely different. The corner coordinates are no longer accurate and there is color table information in the new file, which wasn't present in the original.
Is there any way to handle this conversion so that the bytes aren't altered?