Passing image from js button in browser to Tensorflow.js - javascript

I have an image classifier that takes in images from the user and passes it to Tensorflow.js, but I can't seem to get the image loaded and passed to tf.browser.fromPixels.
I'm new to JavaScript and I'm not sure I'm implementing FileReader correctly.
<body>
<input id="image-selector" type="file">
<button id="predict-button">Predict</button>
<img id="selected-image" src=""/>
</body>
<script type="text/javascript">
document.getElementById("predict-button").onclick = async function() {run()};
async function run() {
let reader = new FileReader();
let dataURL = reader.result;
document.getElementById("selected-image").src=dataURL;
const image = tf.browser.fromPixels(selected-image);
const resized_image = tf.image.resizeBilinear(image, [300,300]).toFloat();
const batchedImage = resized_image.expandDims(0);
const MODEL_URL = 'web_model/model.json';
const model = await tf.loadGraphModel(MODEL_URL);
const result = model.predict(batchedImage);
result.print();
}
</script>

Related

How can I load text file in javascript using fileReader? [duplicate]

This question already has answers here:
Javascript read file without using input
(3 answers)
Closed 9 months ago.
I'm trying to load simple text file in javascript, unfortunately with no success.
my code is:
var my_text:any;
var my_file:File = new File([], "C:\\Users\\riki7\\Downloads\\classes.txt");
var reader = new FileReader();
reader.onload = function() {
my_text = reader.result;
};
reader.readAsText(my_file);
alert(my_text);
after this code runs, I would expect to see classes.txt file content in pop-up alert, instead I get 'undefined'.
my file contains a, b, c.
does anyone know what is my problem? maybe the first parameter for File() constructor?
You have to use html tag <input type="file" id="input" /> and then hung a event listener on it, like that
const inputElement = document.getElementById("input");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
const fileList = this.files; /* now you can work with the file list */
}
then after simply bypass your file into the FileReader
const reader = new FileReader();
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
And i guess that would be it.
You can find more examples there: https://developer.mozilla.org/en-US/docs/Web/API/File_API/Using_files_from_web_applications
Having your code where your alert runs upfront the callback function. If you need to see alter with the content, simply move your alert into the callback function:
reader.onload = function() {
my_text = reader.result;
alert(my_text);
};
because my_text is not ready when you call alert outside.
<input type="file" id="selectedFile">
<p id="display"></p>
<script>
var fr = new FileReader();
let test;
document.getElementById('selectedFile').addEventListener('change', x);
function x() {
fr.onload = ()=>{
document.getElementById('display').innerText = fr.result;
test = fr.result;
alert(fr.result);
}
fr.readAsText(this.files[0]);
}
</script>
<html>
<head>
<script>
var fileReadEvent = function(event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
var text = reader.result;
alert(text)
};
};
</script>
</head>
<body>
<input type='file' accept='text/plain' onchange='fileReadEvent(event)'><br>
</body>
</html>

Storing data as Streamer javascript

I have a large datasets which i am retrieving via tableau API call. im using async await to call the data and storing this as txt extension.
How i am retrieving the data is by using this script below, script is working as expected and the logic i came out with is
Retrieve data records via api call
Append data into div element
Once data is fully loaded to div, use file streamer to save records as txt file
script used -
<!DOCTYPE html>
<html>
<head>
<title>getData() Basic Example</title>
<script type="text/javascript" src="https://public.tableau.com/javascripts/api/tableau-2.min.js"></script>
<script type="text/javascript">
var viz, sheet, table;
function initViz() {
var containerDiv = document.getElementById("vizContainer"),
url = "http://public.tableau.com/views/RegionalSampleWorkbook/Storms",
options = {
hideTabs: true,
hideToolbar: true,
onFirstInteractive: function () {
document.getElementById('getData').disabled = false; // Enable our button
}
};
viz = new tableau.Viz(containerDiv, url, options);
}
async function savefile(data){
const newHandle = await window.showSaveFilePicker();
const writableStream = await newHandle.createWritable();
await writableStream.write(data)
await writableStream.close();
}
function getUnderlyingData(){
sheet = viz.getWorkbook().getActiveSheet().getWorksheets().get("Storm Map Sheet");
sheet.getUnderlyingDataAsync().then(function(dataTable){
let _tmpdata = ''
for(let i = 0; i < dataTable.getData().length;i++){
for(let a = 0; a < dataTable.getColumns().length;a++){
_tmpdata = dataTable.getData()[i][a].formattedValue;
document.getElementById('storage').innerHTML += _tmpdata
}
}
let whatisthis = document.getElementById('storage').innerHTML
savefile(whatisthis)
});
}
</script>
</head>
<body onload="initViz();">
<div class="page-header">
<button id="getData" onclick="getUnderlyingData()" class="btn" disabled>Get Data</button>
<div id="storage"></div>
</div>
<div id="vizContainer" style="width:600px; height:600px;"></div>
<div id="dataTarget"></div>
</body>
</html>
This is working as expected but what worries me is when i have super large volume of data, the alternative logic i have in mind which i tried to implement is as follow
create streamer inside getunderlyingdata function
append data directly in for loop
New logic i tried, ets say saveFile() does not exist and writableStream are directy implemented in getUnderlyingData, this is script i tried
async function getUnderlyingData(){
// save file to location
const newHandle = await window.showSaveFilePicker();
const writableStream = await newHandle.createWritable();
sheet = viz.getWorkbook().getActiveSheet().getWorksheets().get("Storm Map Sheet");
sheet.getUnderlyingDataAsync().then(async function(dataTable){
let _tmpdata = ''
for(let i = 0; i < dataTable.getData().length;i++){
for(let a = 0; a < dataTable.getColumns().length;a++){
_tmpdata = dataTable.getData()[i][a].formattedValue;
// Write data to stream
await writableStream.write(_tmpdata)
}
}
});
// Close Sream
await writableStream.close();
}
It was not able to capture the data is because the page get reloaded as soon as i tried to save to a location . Is it possible to disable the page reload when a location is selected to save the file ?

How to get value of input type = file and display it on a dynamically created image?

I have the following code:
function displayImg() {
let fileUpload = document.getElementById("fileUpload").value;
let container document.getElementById("container");
container.innerHTML = `<img src="fileUpload">`
}
<input type = file id = "fileUpload" accept = "image/*">
<button onclick = "displayImg()">Click to show</button>
<div id="container"></div>
I want it so that the user can input the file into the file Input field and it is placed into the source of a dynamically-created image upon button click. How do I do this?
You can try this
<html>
<body>
<input type = file id = "fileUpload" accept = "image/*">
<button onclick = "displayImg()">Click to show</button>
<div id="container">
<img id="img"></div>
<script>
function displayImg() {
let fileUpload = document.getElementById("fileUpload").value;
//alert(fileUpload);
let image = document.getElementById("img");
img.src = fileUpload;
}
</script>
</body>
</html>
NOTE: The value property only returns the name of the file so the image should be located in the same folder as that of code.Or if you want to, you can add the path of the file before.
please use the below code:
var uploadedFileURL;
function handleFile() {
var fileUploadControl = document.getElementById('fileUpload');
var file = fileUploadControl.files[0];
if (file) {
var reader = new FileReader();
reader.onload = function() {
uploadedFileURL = reader.result;
};
reader.readAsDataURL(file);
}
}
function displayImg() {
var fileUpload = document.getElementById("fileUpload").value;
var container = document.getElementById("container");
container.innerHTML = `<img src="${uploadedFileURL}">`;
}
<input id="fileUpload" type="file" onchange="handleFile()" accept="image/*" />
<button onclick="displayImg()">Click to show</button>
<div id="container"></div>
Here is a solution :
<input type="file" id="fileUpload" accept="image/*">
<button onclick="displayImg()">Click to show</button>
<div id="container">
<img id="img"></img>
</div>
<script>
let displayImg = () => {
let reader = new FileReader();
let input = document.getElementById('fileUpload');
reader.onload = () => {
let img = document.getElementById('img');
img.src = reader.result;
};
reader.readAsDataURL(input.files[0]);
};
</script>

How to display a pdf in the browser when uploading the pdf file

I'm working on a project and I want to display a pdf file as well as a text file in my web page
I did manage to display the contents of a text file.
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = (function(reader) {
return function() {
var contents = reader.result;
var lines = contents.split('\n');
document.getElementById('container').innerHTML = contents;
}
})(reader);
reader.readAsText(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
<input type="file" id="files" name="file" />
<div class="container">
<div class="backdrop">
<div class="highlights"></div>
</div>
<textarea id="container" style="height: 500px; min-width: 500px"></textarea>
</div>
I want to display both text files and PDF files, thanks for your help guys
You can use PDF.js which is community developed and supported by Mozilla Labs.
Looking at their example "Rendering the Page" is the golden ticket here.
I started off the example by breaking out 2 functions (1 to handle the text files and 1 to handle the PDF files) Take a look at the handlePDFFile function and you'll see its somewhat similar, a big difference is we read the file as reader.readAsDataURL(file); instead of reading it as text for the PDF.js library.
for PDF path you will still need to read the file and send the contents of the file to the pdfjsLib.getDocument function. After the loading promise is resolved you will be able to handle the pdf object.
with the pdf object we get the first page and render it onto our canvas. This is only an example so you will need to build on this if you wanted to view multiple pages (only the first page is hard coded).
const PDF_TYPE = "application/pdf";
const TXT_TYPE = "text/plain";
document.getElementById('files').addEventListener('change', handleFileSelect, false);
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
for (var i = 0, f; f = files[i]; i++) {
let fileType = files[i].type;
if (fileType === PDF_TYPE) {
handlePDFFile(files[i]);
} else if (fileType === TXT_TYPE) {
handleTxtFile(files[i])
} else {
console.error(`cannot handle file type: ${fileType}`)
}
}
}
function handleTxtFile(file) {
var reader = new FileReader();
reader.onload = (function(reader) {
return function() {
var contents = reader.result;
var lines = contents.split('\n');
document.getElementById('container').innerHTML = contents;
}
})(reader);
reader.readAsText(file);
}
function handlePDFFile(file) {
var reader = new FileReader();
reader.onload = (function(reader) {
return function() {
var contents = reader.result;
var loadingTask = pdfjsLib.getDocument(contents);
loadingTask.promise.then(function(pdf) {
pdf.getPage(1).then(function(page) {
var scale = 1.5;
var viewport = page.getViewport({
scale: scale,
});
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
});
}
})(reader);
reader.readAsDataURL(file);
}
#the-canvas {
outline: black 3px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.2.2/pdf.min.js"></script>
<input type="file" id="files" name="file" />
<div class="container">
<div class="backdrop">
<div class="highlights">
</div>
</div>
<textarea id="container" style="height: 200px; min-width: 200px"></textarea>
<canvas id="the-canvas"></canvas>
</div>
FOR PDF
Upload your PDF file in Google drive and use its URL in a iframe(like Google Drive) and use its URL in a iframe
<object data="data/test.pdf" type="application/pdf" width="500" height="300">
file.pdf
</object>
Also see this link:-How to Use pdf.js

Parse Uploaded CSV file using D3.js

I'm new to d3.js so I know this might seem as a silly question to some so please bear with me. I'm trying to parse a csv file which a user uploads and print it's output in the console. I'm able to parse the CSV file when I provide the absolute path of the CSV file but when I try doing the same with file upload functionality I'm not getting any output in the console..
Working Javascript Code..
var dataset = [];
d3.csv("sample.csv", function(data) {
dataset = data.map(function(d) { return [ d["Title"], d["Category"], d["ASIN/ISBN"], d["Item Total"] ]; });
console.log(dataset[0]);
console.log(dataset.length);
});
Console Output...
["Men's Brooks Ghost 8 Running Shoe Black/High Risk Red/Silver Size 11.5 M US", "Shoes", "B00QH1KYV6", "$120.00 "]
8
New HTML code..
<input type="file" id="csvfile" name="uploadCSV"/>
<br/>
<button onclick="howdy()">submit</button>
Modified Javascript Code(not working)..
var myfile = $("#csvfile").prop('files')[0];
var reader = new FileReader();
reader.onload = function(e) {
var text = reader.result;
}
reader.readAsDataURL(myfile);
var dataset = [];
d3.csv(reader.result , function(data) {
dataset = data.map(function(d) { return [ d["Title"], d["Category"], d["ASIN/ISBN"], d["Item Total"] ]; });
console.log(dataset[0]);
console.log(dataset.length);
})
Since there was no official documentation on how to handle user uploaded CSV file I can't figure out where I'm going wrong..Is there a way I can use HTML5 file reader?? Please help..
You are close but you don't need to and can't call d3.csv on a reader.result. d3.csv makes an async AJAX call to retrieve a CSV file from a server. You already have the file contents and just want to parse, so use d3.csv.parse.
Full working example:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<input type="file" onchange="loadFile()" />
<script>
var reader = new FileReader();
function loadFile() {
var file = document.querySelector('input[type=file]').files[0];
reader.addEventListener("load", parseFile, false);
if (file) {
reader.readAsText(file);
}
}
function parseFile(){
var doesColumnExist = false;
var data = d3.csv.parse(reader.result, function(d){
doesColumnExist = d.hasOwnProperty("someColumn");
return d;
});
console.log(doesColumnExist);
}
</script>
</body>
</html>
This is for d3-csv#3
<!-- https://www.jsdelivr.com/package/npm/d3-dsv -->
<script src="https://cdn.jsdelivr.net/npm/d3-dsv#3.0.1/dist/d3-dsv.min.js" integrity="sha256-IrzYc2a3nTkfvgAyowm/WKmIGdVCMCcccPtz+Y2y6VI=" crossorigin="anonymous"></script>
<input type="file" accept=".csv">
<button>test button</button>
<script>
const testData = `owner,repo,"branch name"
foo,demo,master
boo,"js awesome",sha1123456
`
document.querySelector(`input`).onchange = async e => {
const input = e.target
const file = input.files[0]
const reader = new FileReader()
reader.readAsText(new Blob(
[file],
{"type": file.type}
))
const fileContent = await new Promise(resolve => {
reader.onloadend = (event) => {
resolve(event.target.result)
}
})
const csvData = d3.csvParse(fileContent)
console.log(csvData)
}
document.querySelector(`button`).onclick = e => {
const csvData = d3.csvParse(testData)
console.log(csvData)
}
</script>
The below link may help you know the implementation of csvParse
csv.js : The csv, tsv(tab) are dependent by dsv.js
dsv.js
If you just load the CSV only then do not import the whole JS. (instead of the d3-csv.js)
https://cdn.jsdelivr.net/npm/d3#7.0.1/dist/d3.min.js
https://cdn.jsdelivr.net/npm/d3-dsv#3.0.1/dist/d3-dsv.min.js
This is an old question and I think we have to clarify some points.
How to load a local csv file
How to link the loaded file with D3
1. Load a file is very simple just check this example:
const fileInput = document.getElementById('csv')
const readFile = e => {
const reader = new FileReader()
reader.onload = () => {
document.getElementById('out').textContent = reader.result
}
reader.readAsBinaryString(fileInput.files[0])
}
fileInput.onchange = readFile
<div>
<p>Select local CSV File:</p>
<input id="csv" type="file" accept=".csv">
</div>
<pre id="out"><p>File contents will appear here</p></pre>
Here we have a simple input element with type="file" attribute, this lets us to pick a csv file. Then the readFile() function will be triggered whenever a file is selected and will call the onload function after reading the file as a binary string.
2. I recommend to use readAsDataURL() to integrate it with d3 like this:
const fileInput = document.getElementById('csv')
const previewCSVData = async dataurl => {
const d = await d3.csv(dataurl)
console.log(d)
}
const readFile = e => {
const file = fileInput.files[0]
const reader = new FileReader()
reader.onload = () => {
const dataUrl = reader.result;
previewCSVData(dataUrl)
}
reader.readAsDataURL(file)
}
fileInput.onchange = readFile
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div>
<p>Select local CSV File:</p>
<input id="csv" type="file" accept=".csv">
</div>
<pre id="out"><p>File contents will appear here</p></pre>
To integrate the loaded file we call previewCSVData() and pass the file then we parse it using d3.csv() method. Also lets use await because it is an asynchronous call.
Note:
d3.csv internally uses fetch and works for any type of URL, (httpURL, dataURL, blobURL, etc...)

Categories