How can I use Node FileSystem to open a file but have it sent to and read by the FileReader API?
const myFile = "C:\\Users\\Me\\Image.png";
fs.readFile(myFile, (error, data) => {
const blob = new Blob(data);
const fileReader = new FileReader();
fileReader.readAsDataURL(blob);
fileReader.addEventListener("load", () => {
const image = new Image();
image.src = fileReader.result;
document.body.appendChild(image);
});
});
This code doesn't throw an errors, but it doesn't work.
Thanks to the participants in the discussion above, the following code is a working solution. I've purposefully left out error handling for brevity.
const nodeFileSystem = require("fs");
const filePath = "C:\\path\\to\\image\\file.png";
nodeFileSystem.readFile(filePath, (error, data) => {
const blob = new Blob([data]);
const fileReader = new FileReader();
fileReader.readAsDataURL(blob);
fileReader.addEventListener("load", fileReaderLoadHandler);
});
function fileReaderLoadHandler(event) {
const fileReader = event.target;
fileReader.removeEventListener("load", fileReaderLoadHandler);
const image = new Image();
image.src = fileReader.result;
image.addEventListener("load", imageLoadHandler);
}
function imageLoadHandler(event) {
const image = event.target;
image.removeEventListener("load", imageLoadHandler);
document.body.appendChild(image);
}
Related
Here is code which i'm using to resize and compress images in javascript this working correctly and also send one image by ajax in mysql but issue is i want to send four images in database also some extra fields. Now i want imgCompressResize function just pass image parameter and return compress and resized image so i can save as i need.
<input type="file" name="img1" id="file1" accept="image/*">
document.getElementById("file1").addEventListener("change", function (e) {
var file = imgCompressResize(e);
var data = new FormData();
data.append('file1', file);
$.ajax({
url:"page.php",
type:"POST",
data:data,
cache: false,
contentType: false,
processData: false,
success:function (data) {
alert(data);
}
});
});
function imgCompressResize(e) {
const width = 500;
const height = 600;
var file;
const fileName = e.target.files[0].name;
console.log(fileName);
const reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);
reader.onload = event => {
const img = new Image();
img.src = event.target.result;
img.onload = () => {
const elem = document.createElement('canvas');
elem.width = width;
elem.height = height;
const ctx = elem.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
ctx.canvas.toBlob((blob) => {
file = new File([blob], fileName, {
type: 'image/jpeg',
lastModified: Date.now()
});
return file;
// if i call here ajax() function that working for one image but i don't need
// call here ajax().
}, 'image/jpeg', .7);
},
reader.onerror = error => console.log(error);
}
}
I'm not going to rewrite this whole thing but simply give you an overview of using promises since onload is asynchronous.
document.getElementById("file1").addEventListener("change", function(e) {
const filesArray = Array.from(this.files);
// map array of each resize promise
const filePromises = filesArray.map(imgCompressResize);
var data = new FormData();
// when all resolved append to FormData
Promise.all(filePromises).then(newFiles =>{
newFiles.forEach(f=> data.append('files[]', f)
});
// append other fields needed
//then do ajax
})
function imgCompressResize(file) {
// ^^ file instead of event
// return promise
return new Promise((resolve, reject) => {
//...
//const fileName = e.target.files[0].name;
const fileName = file.name;
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = event => {
//...
img.onload = () => {
//....
const newFile = new File([blob], fileName, {...);
// resolve the promise
resolve(newFile);
});
});
});
reader.onerror = reject
}
I am able to read/parse excel files on the front end using the below code with FileReader and xlsx package. However, for very large files, this will crash the browser. I only need to read the first few rows, how can i achieve this?
working code
const xlsxParse = (file) => {
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
let readedData = XLSX.read(data, { type: 'binary' });
const wsname = readedData.SheetNames[0];
const ws = readedData.Sheets[wsname];
/* Convert array to json*/
const dataParse = XLSX.utils.sheet_to_json(ws, { header: 1 });
};
reader.readAsBinaryString(file)
}
my attempt to read first few rows. not working
const xlsxParse = (file) => {
var reader = new FileReader();
reader.onprogress = (e) => {
var data = e.target.result;
let readedData = XLSX.read(data, { type: 'binary' });
if (readedData) {
const wsname = readedData.SheetNames[0];
const ws = readedData.Sheets[wsname];
/* Convert array to json*/
const dataParse = XLSX.utils.sheet_to_json(ws, { header: 1 });
console.log('dataParse', dataParse)
if (dataParse.length > 3) {
reader.abort()
}
}
reader.readAsBinaryString(file)
}
thanks
This can help you out. Basically, sheetRows is standing for reading the first n lines:
handleFile = (file /*:File*/) => {
/* Boilerplate to set up FileReader */
const reader = new FileReader();
const rABS = !!reader.readAsBinaryString;
reader.onload = e => {
/* Parse data */
const bstr = e.target.result;
const wb = XLSX.read(bstr, { type: "binary", sheetRows: 100});
/* Get first worksheet */
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
/* Convert array of arrays */
const data = XLSX.utils.sheet_to_json(ws);
const tableColumns = Object.keys(data[0]);
console.log('data', data);
};
if (rABS) reader.readAsBinaryString(file);
else reader.readAsArrayBuffer(file);
};
I tried to convert a base64 string generated from pdf file using FileReader.readAsDataURL() to its original format.In NodeJS I did it like this and it was able generated the pdf to its initial state.
filebuffer = "data:application/pdf;base64,JVBERi0xLjQKJSDi48/..........."
let base64file = fileBuffer.split(';base64,').pop();
fs.writeFileSync('download.pdf',base64file,{encoding:'base64'},function(err){
if(err === null){
console.log("file created");
return;
}
else{
console.log(err);
return;
}
})
But i tried to do it in HTML + Javascript in this way.But in this way , pdf was empty/no letter wasn't in it
let stringval = "data:application/pdf;base64,JVBERi0xLjQKJSDi48/..........."
let encodedString = stringval.split(';base64,').pop();
let data = atob(encodedString);
let blob = new Blob([data]);
// //if you need a literal File object
let file = new File([blob], "filename");
link.href = URL.createObjectURL(file);
link.download = 'filename';
I was Capturing file and converting to base64 string in this way:
captureFile: function () {
event.preventDefault();
const file = event.target.files[0];
$("#labelinput1").html(file.name);
const reader = new window.FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
var x = reader.result.toString();
App.buffer2 = x;
console.log("buffer", App.buffer);
};}
Then after clicking a button , I added the buffer to IPFS node
addfile: async function () {
if (App.buffer2 === null) return;
App.node = await window.Ipfs.create()
App.node.add(App.buffer2, function (errx, resipfs) {
if (errx === null) {
console.log(resipfs[0].hash);
App.buffer2 = null;
return App.showInfo(resipfs[0].hash);
}
else {
return App.showError(errx.message.toString() + errx.stack.toString());
}
});
}
using the IPFS HASH i can get back the base64 encoded string , I retrieved this string in this way:
ipfsfiledownload: async function () {
var filebuffer = await App.node.cat(hashtext);
var stringval = filebuffer.toString();
//convert this string to main file
}
I used Truffle Petshop and write those functions in top of it. Here is a IPFS hash QmfSefUiwjV44hpfnHyUngGATyHm9M4vN3PzF1mpe59Nn1. you can try out this Hash value in nodejs with this code
const IPFS = require('ipfs');
const fs = require('fs');
const main = async() => {
const node = await IPFS.create()
var fileBuffer = await
node.cat('QmfSefUiwjV44hpfnHyUngGATyHm9M4vN3PzF1mpe59Nn1')
fileBuffer = fileBuffer.toString()
let base64file = fileBuffer.split(';base64,').pop();
fs.writeFileSync('download.pdf',base64file, {encoding:'base64'},function(err){
if(err === null){
console.log("file created");
return;
}
else{
console.log(err);
return;
}
})
}
main()
You can find the full code here.
What I am doing wrong and how to solve it?
After converting the base64 string using atob() , I converted it to Uint8Array Then created the blob and file . It seems to work now ..
Here is the full code :
ipfsfiledownload: async function () {
var hashtext = document.getElementById("id_ipfshash").value //getting the IPFS HASH
var link = document.getElementById("downloadLink");
if (hashtext === null) return
var filebuffer = await App.node.cat(hashtext); //getting the base64 string from IPFS
var stringval = filebuffer.toString();
console.log(stringval);
let encodedString = stringval.split(',')[1]; //getting the base64 hash
let mimetype = stringval.split(',')[0].split(':')[1].split(';')[0]; //getting the mime type
let data = atob(encodedString); //ascii to binary
var ab = new ArrayBuffer(data.length);
var ia = new Uint8Array(ab);
//converting to Uint8Array
for(var i = 0;i<data.length;i++){
ia[i] = data.charCodeAt(i);
}
let blob = new Blob([ia],{ "type": mimetype});
let filename = 'filename.' + App.getExtension(mimetype);
let file = new File([blob], filename);
link.href = window.URL.createObjectURL(file);
link.download = filename;
link.click();
}
I am using tensorflowjs to do some front-end image classification. I am trying to use tf.browser.fromPixels to convert an img element to a tensor. However, I am getting all zeros of shape [160, 160, 3]. I am using the FileReader api to read an image from the file system via the <input type="file"> element. Here's some of the code:
function getFiles(event) {
const files = event.target.files;
let tempStore = [];
for (let i = 0; i < files.length; ++i) {
tempStore.push(files[i]);
}
return tempStore;
}
const imageElement = document.getElementById("upload");
imageElement.addEventListener("change", event => {
const files = getFiles(event);
Promise.all(files.map(loadImg)).then(d => {
console.log("All done !!!", d);
});
});
const loadImg = imgFile => {
return new Promise((resolve, reject) => {
let reader = new FileReader();
let imgEl = document.createElement("img");
reader.onload = async e => {
imgEl.src = e.target.result;
imgEl.setAttribute("width", 160);
imgEl.setAttribute("height", 160);
document.body.append(imgEl);
const fromPixels = tf.browser.fromPixels(imgEl);
resolve(fromPixels);
};
reader.onerror = reject;
reader.readAsDataURL(imgFile);
});
};
The image gets appended to document body properly.
The imageElement is of the form:
<img src="data:image/jpeg;base64,....." width=160 height=160>
You are creating the tensor from the image when the img tag has not yet been loaded. Here is the way to go
imgEl.src = e.target.result;
imgEl.setAttribute("width", 160);
imgEl.setAttribute("height", 160);
document.body.append(imgEl);
im.onload = () => {
// create the tensor after the image has loaded
const fromPixels = tf.browser.fromPixels(imgEl);
resolve(fromPixels);
}
I want to resize an image before uploading it to the server (with Firebase):
api.uploadPhoto = async (file = {}, field = {}) => {
const canvas = document.getElementById('canvas')
const img = document.createElement('img')
const reader = new FileReader()
let fileToUpload
reader.onload = function (e) {
img.src = e.target.result
pica.resize(img, canvas).then(result => {
fileToUpload = pica.toBlob(result, 'image/jpeg', 90))
})
}
reader.readAsDataURL(file)
// run the code below only when reader.onload has finished
return await imageUpload.toFirebase(fileToUpload, field)
}
The problem is that imageUpload.toFirebase is running before reader.onload. How to fix this?
move the upload in to the callback ...
api.uploadPhoto = async (file = {}, field = {}, callback) => {
const canvas = document.getElementById('canvas');
const img = document.createElement('img');
const reader = new FileReader();
let fileToUpload;
reader.onload = function (e) {
img.src = e.target.result;
pica.resize(img, canvas).then(result => {
fileToUpload = pica.toBlob(result, 'image/jpeg', 90));
});
reader.readAsDataURL(file);
callback(await imageUpload.toFirebase(fileToUpload, field));
}
};