Using a pre-trained model for image classification, I created a webpage that in theory will allow the user to browse their computer for a image and when that image is selected, it is automatically processed and the top three responses for what that image most likely is displayed on the webpage along with the probability for each. My JS function is probably very wrong, I’m somewhat self-taught. I’m also using materializecss and tensorflow.js if it helps.
I’m having trouble with changing the image I currently have hard coded there with the chosen image of the user.
HTML
<div name="imagePost" class="offset-s1 col s6">
<img class="responsive-img" id="changeImage" src="images/dog.jpg" alt="description">
<input type="file" name="pickImage" onchange="swapImage(pickImage)">
</div>
JS Function
function swapImage (pickImage) {
var image_toShow = pickImage;
document.getElementById('changeImage').innerHTML = image_toShow;
}
Here is how you can swap the image
function swapImage(event) {
var selectedFile = event.target.files[0];
var reader = new FileReader();
const img = document.getElementById("changeImage");
reader.onload = function(event) {
img.src = event.target.result;
};
reader.readAsDataURL(selectedFile);
}
Thanks for the help and suggestions. I ended up using a file reader, eventlisteners, and actually creating the img tag in another js function. Ill share it below incase it could help others. So the html part just has a empty div and js reads the input file and creates a img tag with the uploaded photo.
<div name="imagePost" class="offset-s1 col s6">
<fieldset>
<div id="changeImage">
</div>
</fieldset>
<input type="file" id="pickImage">
<a class="btn-large black col s4 offset-s1 unselect" onclick="app()">Calculate</a>
</div>
</div>
window.onload=function()
{
var y = document.getElementById("pickImage");
y.addEventListener('change', loadimage, false);
}
function imageHandler(e2)
{
var store = document.getElementById('changeImage');
store.innerHTML='<img id="newImage" class="responsive-img" src="' + e2.target.result +'" alt="The image here is interchangeable, allowing for users to process many different images using the machine learning model.">';
}
function loadimage(e1)
{
var filename = e1.target.files[0];
var fr = new FileReader();
fr.onload = imageHandler;
fr.readAsDataURL(filename);
}
Related
So I'm Making a meme generator and the user has the option to enter an image link OR upload a local file from storage.
Here is my html for link/local storage upload.
<div class="Main_Grid_Item Link_Upload_Div">
<form action="/" method="POST">
<p>Enter Image Link:</p>
<input class="Image_Input" type="text" name="Link_Url" placeholder="Image Link"><br>
<button class="Image_Submit" type="submit" name="button">Submit Image</button>
</form>
</div>
<div class="Main_Grid_Item File_Upload_Div">
<form>
<p>Upload Image:</p>
<input id = "UploadOutput" class = "Upload_Output" type="text" placeholder="Image Name After Upload" readonly><br>
<label for="ImgStorage" class="Image_Upload_Label">Upload Image</label>
<input type='file' id="ImgStorage" />
</form>
<br>
</div>
And for specifically file uploading this is my javascript which was mostly copied from this stack thread: Javascript image upload and display
function readURL(input) {
//if picture exists then create a new FileReader
if (input.files && input.files[0]) {
var reader = new FileReader();
//the image with specified id gets url
reader.onload = function (e) {
$("#blah").attr("src", e.target.result);
};
//reads picture
reader.readAsDataURL(input.files[0]);
}
}
Just to clarify that entering a link/uploading an images DOES WORK both ways and the image is shown properly on screen. The problem that I'm facing is when taking a "screenshot" with html 2 canvas.
This is my javascript code for taking a screenshot with html2canvas
//takes screenshot of Meme with overlay
$("#Save_Meme_Button").on("click", memeScreenShot);
function memeScreenShot() {
html2canvas(document.querySelector(".Main_Image_Div")).then((canvas) => {
document.body.appendChild(canvas);
});
}
This code essentially takes a "screenshot" of the image and then shows it below the website. The problem is that when I upload an image with a url, "screenshotting" the image will sometimes produce a blank image.
However if I go to the image-url, download the image on local storage, and then use the other option to upload an image from local storage, the image is saved sucessfully instead of showing a blank image.
Is there any reason why a blank screenshot of the image sometimes happens when uploaded by link compared to being uploaded by local storage? I looked a bit on the docs about something about a tainted canvas but I'm not sure if thats the problem because I get no errors in the console when uploading/saving an image :
https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image#:~:text=Security%20and%20tainted%20canvases,-Because%20the%20pixels&text=As%20soon%20as%20you%20draw,an%20exception%20to%20be%20thrown.
I am getting a cors error when the image is uploaded blank when I enable the option to useCors. I think this is why the link option is not working and the local storage is working
enter image description here
Code that displays image
<div id = "MainImageDiv" class="Main_Image_Div">
<% if(typeof imgUrl !== 'undefined'){ %>
<img id="blah" src=<%= imgUrl %> class="Main_Image" /></img>
<% } else{ %>
<img id="blah" src="/images/stonks.png" class="Main_Image" /></img>
<% } %>
<p id="TopTextPar" class="Top_Text"></p>
<p id="BottomTextPar" class="Bottom_Text"></p>
</div>
Ok so I managed to solve my problem. It's essentially a copy of the solution on this thread : html <img src=...> works but JS Image loading cause CORS error.
What I essentially did was take the image url the user entered and rendered it onto a seperate canvas.
And I enabled cors with this https://cors-anywhere.herokuapp.com/. I got a (cors enabled?) data url out of this and then all I had to do is append an image with the image src as the data url I received.
Here's my solved code :
// Changes image based on link
$("#ImageSubmit").click(function(){
//makes the previous meme dissapear and gets the url of the inputted link
$("#blah").css("display","none");
const imgUrl = $("#ImageInput").val();
function loadImgAsBase64(url, callback) {
//creates camvas amd image element + allows cors + loads image
let canvas = document.createElement('CANVAS');
let img = document.createElement('img');
img.setAttribute('crossorigin', 'anonymous');
img.src = 'https://cors-anywhere.herokuapp.com/' + url;
img.onload = () => {
canvas.height = img.height;
canvas.width = img.width;
let context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
let dataURL = canvas.toDataURL('image/png');
canvas = null;
callback(dataURL);
};
}
loadImgAsBase64(imgUrl, (dataURL) => {
$("#MainImageDiv").append(`<img id="blah" class = "Main_Image Link_Meme"
src="${dataURL}">`);
});
loadImgAsBase64(imgUrl)
});
I use below script for preview an image before it is uploaded.
I have a html like this:
<div>
<img id="image" src="#">
</div>
<input type="file" accept="image/gif, image/jpeg, image/png" onchange="readURL(this);">
and js like this:
(I use jquery-2.0.0.min.js )
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#image').attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
var image = document.getElementById('image');
console.log(image);
}}
My problem is this: when I show image with this script before downloading I can't get image by var image = document.getElementById('image'); and console log show this: <img src="#" id="image">. How I can get image that shown in it before uploading?
FileReader() .readAsDataURL() method returns results asynchronously. Include var image = document.getElementById('image');console.log(image); or console.log($("#image")[0]) within FileReader onload event handler.
The FileReader object lets web applications asynchronously read the
contents of files (or raw data buffers) stored on the user's computer,
using File or Blob objects to specify the file or data to read.
FileReader.readyState Read only
A number indicating the state of the FileReader. This is one of the following:
EMPTY 0 No data has been loaded yet.
LOADING 1 Data is currently being loaded.
DONE 2 The entire read request has been completed.
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
// do stuff when `.readAsDataURL()` completes
var image = document.getElementById("image");
image.src = e.target.result;
console.log(image, e.target.result, reader.DONE);
};
reader.readAsDataURL(input.files[0]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img id="image" src="#" />
</div>
<input type="file" accept="image/gif, image/jpeg, image/png" onchange="readURL(this);">
I'm using a regular HTML File Picker input form item to allow my users to select files. I'd like to show them a thumbnail of the file they selected as they will be required to select many images and it can get confusing.
Does anyone know if it's possible to display the image they selected without uploading it to the server? If so, how?
If someone can point me to a post or give me an idea of how I might do this it will be greatly appreciated.
<input type="file" name="image" accept="image/*">
<!-- Create an <img> element to preview the image -->
<img id="image-preview" width="320">
<!-- The <input> can go anywhere in your page or <form>. Note the "onchange" attribute -->
<input type="file" name="image" accept="image/*" onchange="handleFileChange">
Make sure the following JavaScript comes after the above <img> and <input> elements. You can put this in your .js file that is loaded at the end of the page or in a <script> element at the end of page.
// Select the preview image element
const imgElement = document.getElementById('image-preview');
function handleFileChange(e) {
// If no file was selected, empty the preview <img>
if(!e.target.files.length) return imgElement.src = '';
// Set the <img>'s src to a reference URL to the selected file
return imgElement.src = URL.createObjectURL(e.target.files.item(0))
}
This should get you started
http://jsfiddle.net/41go76g4/
Basically you read the file in with fileAPI in javascript and set the returned blob as the dataURL for an img tag.
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('fileInput').addEventListener('change', handleFileSelect, false);
ref: http://www.html5rocks.com/en/tutorials/file/dndfiles/
Scene: I am trying to display a file image selected from the gallery into a webview using javascricpt and/or jquery but I am not able to do so. The same works while opening the html in a desktop browser.
What I have tried so far is this in the android code is this:
Written the openFileChooser code and getting the image path and also the image bytes.
calling the following in onActivityResult method:
String js = "javascript:loadImage(file://" + imagePath + ")";
mWebView.loadUrl(js);
The html looks like this:
<div class="file_chooser">
<!-- <input type="submit" value="File chooser" id="btnSubmit" onclick="sayHello();" > -->
<input type="file" name="banner_image" id="banner_image" onChange="loadImage(this);" accept="image/*" />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<img alt="" id="image" src="" width="200px" height="200px" onclick="showSrc(this.src);">
</div>
and the javascript looks like this:
<script type="text/javascript">
function loadImage(input) {
if (input.files && input.files[0]) {
Android.alert('input: ' + input.files[0]);
var reader = new FileReader();
reader.onload = (function(input) {
return function(e) {
$('#image').attr('src', e.target.result);
console.log('onload stage finished');
};
})(input);
reader.onloadend = (function() {
// $('#image').src(file.name);
});
reader.readAsDataURL(input.files[0]);
//data:image/jpg;base64,xxxxxxxxxxxxxxxxxxxxxxxxxxxx -> this did not work
}
function showSrc(src) {
Android.alert('src : ' + src);
}
</script>
But i seem to be messing with the android code and also javascript, since i do not know jscript that well.
Please assist as to how to display an image after selection from the gallery.
EDIT:
I have gone through lotsa links that show how to call a javscript function from android , and how to display an image by calling loadBaseUrl with the new html code that has an image inside the src tag, like this, but this is not what I really want.
For those who fall into such a case:
I changed how the loadImage method functions to one that converts a file received into bytes
Steps:
1. Read a file from android and send the path over to the js function
2. Pass the path to a reader and when the reader loads the file, the onLoadEnd method gets called
3. Convert the file to bytes using the code
var stringToReplace = reader.result;
stringToReplace = stringToReplace.replace('data:base64,','data:image\/jpeg;base64,');
Set the image source to the string obtained in #3.
I'm working on an application (in Node.js, which is irrelevant for this case) which allows the user to upload an image. It works fine using a form with an input (type="file") field.
However, what I want is to be able to upload an image using HTML5 drag and drop instead. As far as i've come it's possible to drag an image to the client, and the image thumbnail is displayed in a div. However I really need some help with getting the file upload working.
The thing is that I want to use the form that i'm using right now, and (somehow) pass the file's path to the input field, i.e. the flow will work exactly as it do now, but instead of choosing a file by browsing it I want to attach it to the input field by drag and drop.
In the js code below for drag and drop the file that was dragged to the client is stored in the variable "file", and i'm able to use "file.name", "file.type" and "file.size" exactly the same way as it works since before with the form. However, I can't access the files "path" (file.path) which makes it impossible to access the file server side for uploading the same way as I do it since before.
The question is, is it possible to pass the file object to the input field after the file has been dragged to the client, so that I can click on "submit" and upload the file? If so, how could this be done?
Thanks in advance!
the dropbox as well as the form i'm using for file uploads:
<div id='upload'>
<article>
<div id='holder'>
<p id='status'>File API and FileReader API not supported</p>
</div>
</article>
<form method='post' enctype='multipart/form-data' action='/file-upload'>
<p>
<input type='file' name='thumbnail'>
</p>
<p>
<input type='submit'>
</p>
</form>
</div>
the code for drag and drop:
uploadImage: function(){
var holder = document.getElementById('holder'),
state = document.getElementById('status');
if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'File API & FileReader available';
}
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
holder.style.background = 'url(' + event.target.result + ') no-repeat center';
};
reader.readAsDataURL(file);
return false;
};
},
You cannot use the file input to add the file data.
Nevertheless, what you can do (among other technics) is to use the base64 (natively available through the reader.onload event as event.target.result, when using readAsDataURL method) encoded data and put it into an hidden field :
html
<article>
<div id='holder'>
<p id='status'>File API and FileReader API not supported</p>
</div>
</article>
<form method='post' enctype='multipart/form-data' action='/file-upload'>
<input type='file' name='thumbnail' />
<input type='hidden' name='base64data' />
<input type='submit' formenctype='application/x-www-form-urlencoded' />
</form>
js
reader = new FileReader();
reader.onload = function (event) {
document.getElementById('base64data').setAttribute('value', event.target.result);
};
reader.readAsDataURL(file);
From the server side you'll be able to get the base64 encoded data from the file, just decode it and use it as you want.
While submitting the form, you could also change the "enctype" attribute (done through the formenctype attribute) and remove the basic html file input, since the data will be post in a text field.
It is impossible to know the path of the field for security purposes. With drag and drop you must have it upload independently of the main form. Look here for an example: http://www.sitepoint.com/html5-file-drag-and-drop/
I find that the hidden field set in reader.onload (see answer by #challet) is not set when acccessed in code behind. I am using asp.net and a WebForms project. To access the hidden fields I have to prepend MainContent_ to the field names. aspx code is below
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
...
<script type="text/javascript">
function dropHandler(ev) {
alert("File(s) dropped");
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
//alert("Default prevented");
if (ev.dataTransfer.items) {
if (ev.dataTransfer.items.length > 1) {
alert("Only single files can be dragged and dropped into Caption Pro Web");
return;
}
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[0].kind === 'file') {
var file = ev.dataTransfer.items[0].getAsFile();
document.getElementById("MainContent_DroppedFileName").value = ev.dataTransfer.items[0].name
reader = new FileReader();
reader.onload = function (event) {
document.getElementById('MainContent_DroppedFileContent').value = event.target.result;
};
reader.readAsDataURL(ev.dataTransfer.items[0]);
}
} else {
// Use DataTransfer interface to access the file(s)
if (ev.dataTransfer.files.length > 1) {
alert("Only single files can be dragged and dropped into Caption Pro Web");
return;
}
document.getElementById("MainContent_DroppedFileName").value = ev.dataTransfer.files[0].name
document.getElementById("MainContent_DroppedFileContent").value = "Test";
reader = new FileReader();
reader.onload = function (event) {
document.getElementById("MainContent_DroppedFileContent").value = event.target.result;
};
reader.readAsDataURL(ev.dataTransfer.files[0]);
}
document.getElementById('<%=btnDrop.ClientID %>').click();
}
</script>
...
<div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);">
<p>Drag image to this Drop Zone ...</p>
</div>
<asp:HiddenField ID="DroppedFileName" runat="server" />
<asp:HiddenField ID="DroppedFileContent" runat="server" />
...
</asp:Content>
I access the hidden fields from c# as shown below
protected void btnDrop_Click(object sender, EventArgs e)
{
string FileName = DroppedFileName.Value;
string FileContent = DroppedFileContent.Value;
}
If I use Internet Explorer as the target browser (not running VS as Admin as this disables drag/drop!) and set a breakpoint in the reader.onload() function the hidden field DroppedFileContent contains the encoded file content, but when I try to access it from btnDrop_Click it only contains "Test" as set before reader.onload() and does not contain the encoded file content. The field DroppedFileNam.Value is as set in the Javascript.