I have the following path
"file:///var/mobile/Containers/Data/Application/92C91B4A-B7F9-40F8-B8AD-646DA0607942/Library/NoCloud/Z7sY4cdv_photo_001.jpg"
how can I convert this file path to the actual binary representation of the file? I've tried using the file reader in every way imaginable but keep on getting error codes. THANKS
so my expect result is to have the bytes into a javaScript object, basically assign a image to a object.
try that :
$scope.getFileBinary = function(fileUri){
var xhr = new XMLHttpRequest();
xhr.open("GET", fileUri, true);
//xhr.responseType = 'blob';
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
if (this.status == 200 || this.status === 0) {
// Note: .response instead of .responseText
var blob = new Blob([this.response], {
type: 'image/png'
});
var reader = new FileReader();
reader.onload = function() {
// this gets read of the mime-type data header
var actual_contents = reader.result.slice(reader.result.indexOf(',') + 1);
d.resolve(actual_contents );
};
reader.readAsDataURL(blob);
}
};
xhr.send();
}
Related
I am trying to pass a file that is attached from client-side to server-side.
In order to get a file, I tried these below codes.
1)
var files = event.target.files;
var file = files[0];
2)
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
In the first one, 'file' contains only details about the file and it does not contain the file content and in the second one 'vm.image' file content is there, but it is not in byte code format. I want the file in byte code format in js which I can send in the body of an ajax call!
In order to get the base64 of the file input:
const files = e.target.files || e.dataTransfer.files;
const file = files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
this.image = reader.result.split(',')[1];
};
Here is an example:
document.getElementById('inputFile').addEventListener('input', function(e){
const files = e.target.files || e.dataTransfer.files;
const file = files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
this.image = reader.result.split(',')[1];
console.log(this.image)
};
})
<input type="file" id="inputFile"/>
I have a function that will determine if the gif is animated or non-animated. Everything is working fine, until i upload those gif to the server, and load it, the blob url is a empty string. How can i generate a blob url for this?
Due to the blob url being empty string, i get parameter 1 is not of type 'blob'
The function below determines if the gif is animated or not.
$scope.isNotAnimatedGIF = function(file) {
var reader = new FileReader();
return new Promise(function(resolve, reject) {
reader.onload = function (e) {
var gifInfo = gify.getInfo(reader.result);
if (gifInfo.images.length <= 1) {
file.animatedGIF = false;
resolve(true);
} else {
file.animatedGIF = true;
resolve(false);
}
}
reader.readAsArrayBuffer(file);
});
}
I am using Angular 1.4.10
Thank you !
You can use URL.createObjectURL() to create Blob url.
The URL.createObjectURL() static method creates a DOMString containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.
DEMO
function createbloburl(file, type) {
var blob = new Blob([file], {
type: type || 'application/*'
});
file = window.URL.createObjectURL(blob);
return file;
}
document.querySelector('#file').addEventListener('change', function(e) {
var file = e.currentTarget.files[0];
if (file) {
file = createbloburl(file, file.type);
document.querySelector('iframe').src = file;
//console.log(file)
}
})
<input id="file" type="file">
<iframe src=""></iframe>
try this reader.readAsDataURL(Blob|File).
you can find more from here
I am using ngCropImage to crop an image and want to upload it following this link:
NgCropImage directive is returning me dataURI of the image and I am converting it to a blob (after converting it I get a blob object: which has size and type), Converted DataURI to blob using following code:
/*html*/
<img-crop image="myImage" result-image="myCroppedImage" result-image-size="250"></img-crop>
$scope.myImage='';
$scope.myCroppedImage = {image: ''}
var blob;
//called when user crops
var handleFileSelect=function(evt) {
var file=evt.currentTarget.files[0];
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function($scope){
$scope.myImage=evt.target.result;
});
};
console.log($scope.myCroppedImage)
reader.readAsDataURL(file);
var link = document.createElement('link');
blob = dataURItoBlob($scope.myCroppedImage)
console.log(blob)
};
angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var binary = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: mimeString});
}
$scope.upload = function(file) {
//var file = new File(file, "filename");
// Configure The S3 Object
console.log($scope.creds)
AWS.config.update({ accessKeyId: $.trim($scope.creds.access_key), secretAccessKey: $.trim($scope.creds.secret_key) });
AWS.config.region = 'us-east-1';
var bucket = new AWS.S3({ params: { Bucket: $.trim($scope.creds.bucket) } });
if(file) {
//file.name = 'abc';
var uniqueFileName = $scope.uniqueString() + '-' + file.name;
var params = { Key: file.name , ContentType: file.type, Body: file, ServerSideEncryption: 'AES256' };
bucket.putObject(params, function(err, data) {
if(err) {
// There Was An Error With Your S3 Config
alert(err.message);
return false;
}
else {
// Success!
alert('Upload Done');
}
})
.on('httpUploadProgress',function(progress) {
// Log Progress Information
console.log(Math.round(progress.loaded / progress.total * 100) + '% done');
});
}
else {
// No File Selected
alert('No File Selected');
}
}
$scope.uniqueString = function() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 8; i++ ) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
//for uploading
$scope.handleSave = function(){
$scope.upload(blob);
}
Now, I want to upload this blob on S3 using this, but I am not able to figure out how to upload this blob file to s3 (as I am not getting 'name' in the blob file)
Any help would be really appreciated. Thanks
You can always create file from blob. You can pass file name also.
var file = new File([blob], "filename");
This same file object you can use to upload on s3.
Change your handleSave method to following. File name will be abc.png for now
//for uploading
$scope.handleSave = function(){
blob = dataURItoBlob($scope.myCroppedImage)
$scope.upload(new File([blob], "abc.png"));
}
It is not advisable that you do to put the key
secretAccessKey: $.trim($scope.creds.secret_key)
on the client side ... That is not done !, anyone can manipulate your bucket at will.
I'm using (ngImgCrop) to crop an image and then upload the cropped image to server using (angular-file-upload).
I can get the $dataURI from the "on-change" option in ngImgCrop. But I need a File instace to call $upload.
How can I get the File instance of the cropped image in order to upload :
$scope.upload = $upload.upload({
url: '/api/fileupload',
file: [**file cropped here**]
}).progress(function (evt) {
//
}).success(function (data, status, headers, config) {
//
});
I guess you'll find a proper answer in this method. I found it in Github, in the angular-file-upload issues page (https://github.com/nervgh/angular-file-upload/issues/208):
/**
* Converts data uri to Blob. Necessary for uploading.
* #see
* http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
* #param {String} dataURI
* #return {Blob}
*/
var dataURItoBlob = function(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: mimeString});
};
You should be able to get a file instance doing something like this:
var blob = dataURItoBlob($scope.croppedImage);
I don't know if it works in the good way, but it seems.
try something like:
var uploader = $scope.uploader = new FileUploader({
url: '/saveImagePath',
autoUpload: false
});
angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
var handleFileSelect=function(evt) {
var file=evt.currentTarget.files[0];
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function($scope){
$scope.myImage=evt.target.result;
});
};
reader.readAsDataURL(file);
};
the uploader doesn't support base64 images so you'll need to convert the cropped image from base64 to blob
function base64ToBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
you have to manually attach the files to the queue like this:
$scope.submit = function () {
var file = base64ToBlob($scope.currentPortfolio.croppedImage.replace('data:image/png;base64,',''), 'image/jpeg');
uploader.addToQueue(file);
uploader.uploadAll();
};
in the server side, you got two types of files one posted as HTML file and another un base64 which is the cropped image.
I am new to the mean stack. I want to know how to upload an image file to the database(mongoose) through angularjs. If possible, please provide me with some code. I have searched the internet but I haven't found any suitable code.
You have plenty ways and tools to achieve what you want. I put one of them here:
For this one I use angular-file-upload as client side. So you need this one in your controller:
$scope.onFileSelect = function(image) {
if (angular.isArray(image)) {
image = image[0];
}
// This is how I handle file types in client side
if (image.type !== 'image/png' && image.type !== 'image/jpeg') {
alert('Only PNG and JPEG are accepted.');
return;
}
$scope.uploadInProgress = true;
$scope.uploadProgress = 0;
$scope.upload = $upload.upload({
url: '/upload/image',
method: 'POST',
file: image
}).progress(function(event) {
$scope.uploadProgress = Math.floor(event.loaded / event.total);
$scope.$apply();
}).success(function(data, status, headers, config) {
$scope.uploadInProgress = false;
// If you need uploaded file immediately
$scope.uploadedImage = JSON.parse(data);
}).error(function(err) {
$scope.uploadInProgress = false;
console.log('Error uploading file: ' + err.message || err);
});
};
And following code in your view (I also added file type handler for modern browsers):
Upload image <input type="file" data-ng-file-select="onFileSelect($files)" accept="image/png, image/jpeg">
<span data-ng-if="uploadInProgress">Upload progress: {{ uploadProgress }}</span>
<img data-ng-src="uploadedImage" data-ng-if="uploadedImage">
For server side, I used node-multiparty.
And this is what you need in your server side route:
app.route('/upload/image')
.post(upload.postImage);
And in server side controller:
var uuid = require('node-uuid'),
multiparty = require('multiparty'),
fs = require('fs');
exports.postImage = function(req, res) {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var file = files.file[0];
var contentType = file.headers['content-type'];
var tmpPath = file.path;
var extIndex = tmpPath.lastIndexOf('.');
var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex);
// uuid is for generating unique filenames.
var fileName = uuid.v4() + extension;
var destPath = 'path/to/where/you/want/to/store/your/files/' + fileName;
// Server side file type checker.
if (contentType !== 'image/png' && contentType !== 'image/jpeg') {
fs.unlink(tmpPath);
return res.status(400).send('Unsupported file type.');
}
fs.rename(tmpPath, destPath, function(err) {
if (err) {
return res.status(400).send('Image is not saved:');
}
return res.json(destPath);
});
});
};
As you can see, I store uploaded files in file system, so I just used node-uuid to give them unique name. If you want to store your files directly in database, you don't need uuid, and in that case, just use Buffer data type.
Also please take care of things like adding angularFileUpload to your angular module dependencies.
I got ENOENT and EXDEV errors. After solving these, below code worked for me.
var uuid = require('node-uuid'),
multiparty = require('multiparty'),
fs = require('fs');
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var file = files.file[0];
var contentType = file.headers['content-type'];
var tmpPath = file.path;
var extIndex = tmpPath.lastIndexOf('.');
var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex);
// uuid is for generating unique filenames.
var fileName = uuid.v4() + extension;
var destPath = appRoot +'/../public/images/profile_images/' + fileName;
// Server side file type checker.
if (contentType !== 'image/png' && contentType !== 'image/jpeg') {
fs.unlink(tmpPath);
return res.status(400).send('Unsupported file type.');
}
var is = fs.createReadStream(tmpPath);
var os = fs.createWriteStream(destPath);
if(is.pipe(os)) {
fs.unlink(tmpPath, function (err) { //To unlink the file from temp path after copy
if (err) {
console.log(err);
}
});
return res.json(destPath);
}else
return res.json('File not uploaded');
});
for variable 'appRoot' do below in express.js
path = require('path');
global.appRoot = path.resolve(__dirname);