Using FileReader to read cloud images in Android browser - javascript

I have the following javascript which provides an image upload button and displays the image:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#target').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#imgInp").change(function(){
readURL(this);
});
The full jsfiddle is here:
http://jsfiddle.net/6NXwv/
This code works on every mobile browser I've tried except for the stock Android browser. Specifically images only fail to load if they are stored remotely but appear in the gallery (for example synced facebook or picasa images). Now I know FileReader is only for LOCAL files however chrome browser, opera, and firefox mobile have no issues.
I checked the FileReader error code, it appears that gallery images from facebook/picasa return NOT_FOUND_ERR:
https://developer.mozilla.org/en-US/docs/Web/API/FileError
If this is a case of FileReader not able to read remote files why does it work in all other mobile browsers?
I can't find anyone else having this exact issue, everything I google keeps returning this result:
Issue with stock Browser picking photos from Gallery
However the mime-type appears to be detected correctly. The mime-type shows up and the filename shows the correct name but the actual data isn't there (also File.size reports '0'). I've been able to recreate this on the stock android browser on 4.4 and 4.3. Haven't tested older versions.
In short when selecting photos via the gallery, local files and new images taken with the camera load correctly but remote facebook/picasa files (on 4.4 at least they have little fb/picasa icons on their thumbnails in the gallery) do not load. Only occurs in stock browser.

The error you face have 2 explanation.
First explanation is that the files "Images" that you tried to read with HTML5 API FileReader are looked or on use by other applications "like Facebook or Picasa" and in this case you can do nothing about it from js unless you have physical access to the hardware "Phone".
second explanation which is more likely is some browsers can't fire the event onload of FileReader because they are not fully supporting this HTML5 API. you can read more about this in caniuse website. And that can be solve by changing the event onload to onloadend.
here is how your code should be :
var reader = new FileReader();
reader.onloadend = function () {
console.log(reader.result);
};
reader.readAsDataURL(file);
here is example: jsfiddle
here is Demo: Demo FileReader Html5

<input id="fileinput" name="arquivo[]" type="file" multiple="multiple" onchange="FileDetails()"/>
<var id="file_List"></var>
<button type="button" onclick="Click()">Click Me!</button>
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"></script>
<script>
// simple routine to put content of file input files into memory
G_Array = [];
G_Cont_Upload = 0;
function Click()
{
var a = 1; // this is only to check the content of global variable as google chrome does not stop inside f_ReadFile
}
function FileDetails()
{
var file_arr = [];
if (typeof (FileReader) != "undefined")
{
var files = $('#fileinput')[0].files;
var reader = [];
for (var i = 0; i < files.length; i++)
{
var FileDet = files[i];
var name = FileDet.name;
var Size = FileDet.size;
var Obj = {Name: FileDet.name, SizeInicial : FileDet.size};
G_Array.push(Obj);
reader[i] = new FileReader();
function f_ReadFile(e)
{
var content = e.target.result;
G_Array[G_Cont_Upload].SizeAtual = content.length;
G_Array[G_Cont_Upload].Content = content; // content base 64
G_Cont_Upload++;
}
reader[i].onload = f_ReadFile;
reader[i].readAsDataURL(FileDet);
}
}
else
{
alert("This browser does not support HTML5 FileReader.");
}
}
</script>
</body>

Related

Paste Image using Javascript onpaste is not working for IE, working with chrome

I am trying to save a image/screenshot through paste Ctrl+V into a div #pasteImageDiv by user. Its working fine with Chrome but not working with IE.
I am using IE10.
Until now, what I have been able to find is that if I paste any text to div #pasteImageDiv, it catch the onpaste event properly, even in IE.
But if I paste an image instead of text, it even doesn't catch onpaste (IE doesn't even enter into the function that handles the onpaste event).
document.getElementById('pasteImageDiv').onpaste = function (event) {
It is working well in Chrome whether I paste a text string or an image.
I hope you understand what kind of issue I am facing. Still, if any additional information is needed, please let me know.
$('#pasteImageHere, #pasteImageDiv').click(function(e){ //on paste image button click
e.preventDefault();
$('#hideOnPaste').hide();
//document.getElementById('pasteImageDiv').click();
document.getElementById('pasteImageDiv').style.backgroundColor = "#F1F1F1";
document.getElementById('pasteImageDiv').onpaste = function (event) {
$('#hideOnPaste').hide();
//console.log(event.clipboardData.getData('image/png'));
// use event.originalEvent.clipboard for newer chrome versions
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
// find pasted image among pasted items
var blob = null;
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") === 0) {
blob = items[i].getAsFile();
}
}
// load image if there is a pasted image
if (blob !== null) {
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result); // data url!
var elem = document.createElement("img");
elem.setAttribute("id", "pastedImage");
elem.setAttribute("height", "200");
elem.setAttribute("width", "300");
document.getElementById("pasteImageDiv").appendChild(elem);
document.getElementById("pastedImage").src = event.target.result;
document.getElementById('inputImageData').value = event.target.result;
console.log($('#inputImageData').val());
$('#pastedImage').css('width', '300px');
$('#pastedImage').css('height', '200px');
document.getElementById("pastedImage").style.height = '200px';
};
reader.readAsDataURL(blob);
$('#removePastedImage').show();
}
}
});
Image paste support was added in IE11:
Starting with IE11, images pasted from the clipboard are base64 encoded by default. Users can now easily and safely copy and paste images from their local file system into contenteditable regions of a website. Prior to IE11, pasting a local image on a live website (across security zones) resulted in a broken image icon, as a security measure to prevent local file access.
IE11 is the first browser that supports both pasting images directly from clipboard (for example, from photo editing software or from PrintScreen) and pasting HTML that incorporates local images (for example, from applications such as Microsoft Office that store images temporarily in local paths). Either DataURI or Blob can be used to encode these images.
References
Enhanced Rich Editing Experiences in IE11
Internet Explorer 11 Developer Guide: Editing

how do i get any images in binary code using js?

I want to make a multiple images upload system with prograss bar. I want to do with simaple code(using jquery or js). I want when user has upload his images on browser and i want to show on browser that images and with upload button he starts uploading image via ajax in his folder.
So questions
1.) Is it possible to show uploaded image (without any complicated code) ?
2.) Do i get a variable or array where uploaded images are stored as base64 code (data:/img:dfd5d/d54fs..... something like this) or encoded?
3.) How do i add progressBar ?
I didn't write any code yet because i dont know how to start. I am new in computer science.
But i find this code on this site
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
This is easy code and i understand but one thing is not clear what does mean this line var reader = new FileReader(); why use new and what is it ?
Ty in advance and please dont explain complicate and i am not very good in english. So please try to explain in poor words if possible..
Assuming that you have this field
<input type="file" onchange="showImage(this)"/>
you can create a script to take the binary data and show it
function showImage(input){
var reader = new FileReader();
// validating...
var fileType = input.files[0].type;
var filesize = input.files[0].size;
// filetype (this will validate mimetype, only png, jpeg, jpg allowed)
var fileTypes = ["image/png", "image/jpeg", "image/gif"];
if (fileTypes.indexOf(fileType) < 0){
// return error, invalid mimetype
return false;
}
// file cannot be more than 500kb
if (filesize > 5000000) {
// return error, image too big
return false;
}
reader.onload = function (e) {
// e will contain the image info
jQuery('#myimagetopreview').attr('src', e.target.result)
}
reader.readAsDataURL(input.files[0]);
}
This should work, if you have problem tell me
edit: FileReader is not supported by all the browsers, check the documentation for more https://developer.mozilla.org/en/docs/Web/API/FileReader
The FileReader in JS has Status "Working Draft" and isn't part of the official JS API. I think you have to wait until the Browsers support this ne API or you have to activate experimental JS API in the Browser.

playing html5 video from in memory source

I am retrieving multiple encrypted data with the help of some ajax queries, and performing some manipulation to transform all theses encrypted chunks into a valid video. And now that I have the binary of the video in memory, I am stuck. How can I display it ?
Just to be sure, I have replicated all theses steps on the server side, and the final output is really a playable video. So my only problem is to display my javascript binary object as a video.
I am doing my best to use only web technologies (html5, video tag, javascript) and I would like to avoid developing my own custom player in flash, which is my very last solution.
if you have an idea, I'm interested. For my part, I am out of imagination.
Here's a quick example that just uses a file input instead of the AJAX you'd normally be using. Note that the first input is wired up to a function that will read the file and return a dataURL for it.
However, since you don't have a fileObject, but instead have a stream of data that represents the contents of the file, you can't use this method. So, I've included a second input, which is wired up to a function that just loads the file as a binary string. This string is then base64 encoded 'manually' with a browser function, before being turned into a dataURL. To do this,you need to know what type of file you're dealing with in order to construct the URL correctly.
It's fairly slow to load even on this laptop i7 and probably sucks memory like no-one's business - mobile phones will likely fall over in a stupor (I haven't tested with one)
You should be able to get your data-stream and continue on from the point where I have the raw data (var rawResult = evt.target.result;)
Error checking is left as an exercise for the reader.
<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
// callback gets data via the .target.result field of the param passed to it.
function loadFileObject(fileObj, loadedCallback)
{
var reader = new FileReader();
reader.onload = loadedCallback;
reader.readAsDataURL( fileObj );
}
// callback gets data via the .target.result field of the param passed to it.
function loadFileAsBinary(fileObj, loadedCallback)
{
var reader = new FileReader();
reader.onload = loadedCallback;
reader.readAsBinaryString( fileObj );
}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
byId('fileInput1').addEventListener('change', onFileInput1Changed, false);
byId('fileInput2').addEventListener('change', onFileInput2Changed, false);
}
function onFileInput1Changed(evt)
{
if (this.files.length != 0)
{
var curFile = this.files[0];
loadFileObject(curFile, onVideoFileReadAsURL);
function onVideoFileReadAsURL(evt)
{
byId('vidTgt').src = evt.target.result;
byId('vidTgt').play();
}
}
}
function onFileInput2Changed(evt)
{
if (this.files.length != 0)
{
var curFile = this.files[0];
loadFileAsBinary(curFile, onVideoFileReadAsBinary);
function onVideoFileReadAsBinary(evt)
{
var rawResult = evt.target.result;
var b64Result = btoa(rawResult);
var prefaceString = "data:" + curFile.type + ";base64,";
// byId('vidTgt').src = "data:video/mp4;base64," + b64Result;
byId('vidTgt').src = prefaceString + b64Result;
byId('vidTgt').play();
}
}
}
</script>
<style>
</style>
</head>
<body>
<input type='file' id='fileInput1'/>
<input type='file' id='fileInput2'/>
<video id='vidTgt' src='vid/The Running Man.mp4'/>
</body>
</html>
To display your video you would need to get an URL for it so that you are able to pass a reference to the video element.
There is URL.createObjectURL which should provide you with such an URL to refer to your data. See https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL for further explanations and mind the compatibility table.
Mozilla hosts an example at https://developer.mozilla.org/samples/domref/file-click-demo.html which displays local files. It should be possible to adapt this to setting the video element's src property instead. Depending on how you store your data, it should be possible to play your video this way.
I tried it in Firefox for data from a File object which left me with a URL blob:https://developer.mozilla.org/ed2e4f2f-57a6-4b06-8d56-d0a1a47a9ffd that I could use to play a video.

JS - file onload() doesn't work with android browser

I have a application similar to the example http://jsfiddle.net/jonathansampson/K3A9r/
But if I use this concept for file upload on a iPad/android it does not work. The image is not loaded into the browser wether with onload() nor with onloadend()
html:
<input type="file" name="myFileSelect" />
js:
// Bind to the change event of our file input
$("input[name='myFileSelect']").on("change", function(){
// Get a reference to the fileList
var files = !!this.files ? this.files : [];
// If no files were selected, or no FileReader support, return
if ( !files.length || !window.FileReader ) return;
// Only proceed if the selected file is an image
if ( /^image/.test( files[0].type ) ) {
// Create a new instance of the FileReader
var reader = new FileReader();
// Read the local file as a DataURL
reader.readAsDataURL( files[0] );
// When loaded, set image data as background of page
reader.onloadend = function(){
$("html").css("background-image", "url(" + this.result + ")");
}
}
});
I don't believe the onloadend event is well supported in android or ios. IE 10 does not support this event on FileReader as well, I think. Perhaps you should rely on the onload event instead.
File.API works from android browser 3.0+
or user firefox on the android device
http://mobilehtml5.org/

Reading client side text file using Javascript

I want to read a file (on the client side) and get the content in an array. It will be just one file. I have the following and it doesn't work. 'query_list' is a textarea where I want to display the content of the file.
<input type="file" id="file" name="file" enctype="multipart/form-data"/>
<script>
document.getElementById('file').addEventListener('change', readFile, false);
function readFile (evt) {
var files = evt.target.files;
var file = files[0];
var fh = fopen(file, 0);
var str = "";
document.getElementById('query_list').textContent = str;
if(fh!=-1) {
length = flength(fh);
str = fread(fh, length);
fclose(fh);
}
document.getElementById('query_list').textContent = str;
}
</script>
How should I go about it? Eventually I want to loop over the array and run some SQL queries.
If you want to read files on the client using HTML5's FileReader, you must use Firefox, Chrome or IE 10+. If that is true, the following example reads a text file on the client.
your example attempts to use fopen that I have never heard of (on the client)
http://jsfiddle.net/k3j48zmt/
document.getElementById('file').addEventListener('change', readFile, false);
function readFile (evt) {
var files = evt.target.files;
var file = files[0];
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result);
}
reader.readAsText(file)
}
For IE<10 support you need to look into using an ActiveX Object like ADO.Stream Scripting.FileSystemObject http://msdn.microsoft.com/en-us/library/2z9ffy99(v=vs.85).aspx but you'll run into a security problem. If you run IE allowing all ActiveX objects (for your website), it should work.
There is such thing as HTML5 File API to access local files picked by user, without uploading them anywhere.
It is quite new feature, but supported by most of modern browsers.
I strongly recommend to check out this great article to see, how you can use it.
There is one problem with this, you can't read big files (~400 MB and larger) because straight forward FileAPI functions attempting to load entire file into memory.
If you need to read big files, or search something there, or navigate by line index check my LineNavigator, which allows you to read, navigate and search in files of any size. Try it in jsFiddle! It is super easy to use:
var navigator = new FileNavigator(file);
navigator.readSomeLines(0, function linesReadHandler(err, index, lines, eof, progress) {
// Some error
if (err) return;
// Process this line bucket
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
// Do something with it
}
// End of file
if (eof) return;
// Continue reading
navigator.readSomeLines(index + lines.length, linesReadHandler);
});
Well I got beat to the answer but its different:
<input type="file" id="fi" />
<button onclick="handleFile(); return false;">click</button>
function handleFile() {
var preview = document.getElementById('prv')
var file = document.getElementById('fi').files[0];
var div = document.body.appendChild(document.createElement("div"));
div.innerHTML = file.getAsText("utf-8");
}
This will work in FF 3.5 - 3.6, and that's it. FF 4 and WebKit you need to use the FileReader as mentioned by Juan Mendes.
For IE you may find a Flash solution.
I work there, but still wanted to contribute because it works well: You can use the filepicker.io read api to do exactly this. You can pass in an dom element and get the contents back, for text or binary data, even in IE8+

Categories

Resources