I have a component which allows me to drag multiple images onto the page and display the preview of those images. The following code achieves that:
displayPreviews(files: FileList) {
for (let i = 0; i < files.length; i++) {
const file = files.item(i);
const reader = new FileReader();
reader.onload = () => {
const image = reader.result as string;
this.uploadFileArray.push({
id: 'id',
image: image,
});
};
reader.readAsDataURL(file);
}
}
----------
<li *ngFor="let image of uploadFileArray">
<div *ngIf="image && image !== ''" [ngStyle]="{'background-image': 'url(' + image.image + ')'}"></div>
</li>
However, when selecting a large amount of images, it slows down the interaction with the rest of the page (form filling etc). I read that reader.readAsArrayBuffer can help alleviate that issue. However, I don't know how to integrate it. The below shows a grey box as it's no longer reading the image in the preview.
detectPhotos(files: FileList) {
for (let i = 0; i < files.length; i++) {
// Reference to a file
const file = files.item(i);
const reader = new FileReader();
reader.onload = () => {
const image = reader.result;
this.uploadFileArray.push({
id: 'id',
image: image,
});
};
reader.readAsArrayBuffer(file);
};
}
One issue of using readAsDataURL, the browser is going to have to convert blob to dataURI and then to display it, it's having to decode the dataURI. If you don't need to process the images first etc, you can use URL.createObjectURL to create a URL that references the BLOB instead.
Be aware, that URL.createObjectURL will keep the blob in memory until you call URL.revokeObjectURL(), it won't get GC'ed until you do. If using something like React, you could attach this to a useEffect dismount, if using pure JS you will want to keep a reference of these to clear when your done.
document.querySelector('input').addEventListener('change', function (e) {
for (const file of e.target.files) {
const url = URL.createObjectURL(file);
const img = document.createElement('img');
img.style.width = "100px";
img.setAttribute('src', url);
img.onload = () => {
URL.revokeObjectURL(url);
};
document.querySelector('#images').appendChild(img);
}
});
<input type="file" name="files" multiple accept="image/*"/>
<div id="images"></div>
Related
I'm trying to be able to upload an image to change a background of a table automatically, but it is only working on Desktop computers, it won’t work on neither IOS nor Android, anyone has any pointers? Thanks in advance.
const frame = document.getElementById('table');
const file = document.getElementById('file');
const reader = new FileReader();
reader.addEventListener("load", function () {
frame.style.backgroundImage = `url(${ reader.result })`;
}, false);
file.addEventListener('change',function() {
const image = this.files[0];
if(image) reader.readAsDataURL(image);
}, false)
Try using object urls
document.body.id = 'table'
const [{style}, file] = document.querySelectorAll('#table, #file')
file.addEventListener('change', img => {
[img] = file.files
style.backgroundImage = img ? `url(${URL.createObjectURL(img)})` : ''
})
<input type=file id=file accept="image/*">
I'm looking forward to save/upload picture in a local directory in Windows using IONIC 3 / Cordova. Indeed, the user has to choose a file (jpg) from a folder, and I want to copy this file in another directory.
I tried with this.file.copyFile(path, name, newPath, newName) but it doesn't work and I don't understand why. I also tried with file-transfer plugin (https://ionicframework.com/docs/native/file-transfer/), but it seems I have to get an endpoint in an API to upload the file.
Please find below the function I use to copy the file when the user clicks on a submit button:
private copyFileToLocalDirBrowser(namePath, currentName, newFileName) {
this.file.copyFile(namePath, currentName, "file:///C://Users//myName//Desktop//imgs//", newFileName).then(success => {
console.log("Picture imported!");
}, error => {
this.presentToast("Error:" + error);
});
}
In the constructor, I declared private file: File and the import is import { File } from '#ionic-native/file';.
The user clicks on an input node (type file), to choose the file he/she wants :
<input name="pictureID" id="inputFile" type="file" (change)="showThumb($event)"/>
And here the showThumb function:
var files = e.target.files;
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) {
//Getting URI :
if (e.target.result) {
this.imageURI = e.target.result;
// Render thumbnail.
var img = document.createElement("img");
img.setAttribute('src', this.imageURI);
img.setAttribute('title', theFile.name);
img.setAttribute('id', "thumb");
document.getElementById('thumb-for-browser').appendChild(img);
}
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
Then, when the user clicks on a "Submit" button, I want to save the picture that I displayed a thumb on a local directory "file:///C://Users//myName//Desktop//imgs//".
Thanks in advance for your help.
Kind regards,
I'm using an old project where I could upload many images but for this one, I only need just one. When uploaded, I should see what's uploaded (preview). When first uploaded, I see the image. If uploaded a different image, I still see the first image. I dont want that, I need to preview the last uploaded image.
JavaScript:
$('.receipt.upload').on('change', function(e) {
let id = e.target.id;
let files = e.target.files;
let image = files[0];
let reader = new FileReader();
reader.onload = function(file) {
let img = new Image();
console.log(file);
img.src = file.target.result;
$('.'+id).replaceWith(img);
}
reader.readAsDataURL(image);
//console.log(files);
});
Rails html.erb:
<div>
<%= image_tag('/assets/receipt/missing-receipt.jpg', class: "receipt#{contract.id}") %>
</div>
// Inside a form
<div>
<%= f.file_field :receipt, id: "receipt#{contract.id}" , class: "receipt upload"%>
</div>
Change these makes no difference:
let files = e.target.files[0];
let image = files;
Created <img> img does not have .className set to <input type="file"> .id. At second change event no element exists in document with id at jQuery() call $('.'+id).
Set the .className of replacement element img to id.
$('.receipt.upload').on('change', function(e) {
let id = e.target.id;
let files = e.target.files;
let image = files[0];
let reader = new FileReader();
reader.onload = function(file) {
let img = new Image();
img.className = id; // set `img` `.className` to `id`
console.log(file);
img.src = file.target.result;
$('.'+id).replaceWith(img);
}
reader.readAsDataURL(image);
});
You don't need the FileReader...
$('.receipt.upload').on('change', function(e) {
let {id, files} = this
let img = new Image
img.src = URL.createObjectURL(files[0])
img.className = id
$('.'+id).replaceWith(img)
})
My basic task is select image and display it,without saving it in database.
For this
1.I have made a select tag in html,through which I can upload the image.
2.I have made a blank image tag in which at there is no image source,alternate is upload image.
3.select tag has onchange javascript event handler which calls javascript function changeimage.
<script>
function changeimage()
{
document.form_name.imagetag.src=document.form_name.filetag.value;
}
</script>
In above Code
form_name : Is the name of my form
<form name = "form_name">
imagetag : Is the name of my Img tag
<Img src=" " name = "imagetag">
filetag : Is the name of my
<input type="file" name = "filetag" onchange="changeimage()">
I have save file using php extension.And when I try to print the value of filetag it shows "C:\fakepath\image.png",display this address for all image.
I have save my php file in www location.
I am using window 7,wamp server and chrome latest version.
You may want to checkout this solution (where my code derives from). It involves a little bit of jQuery but if you truly must write it out in pure JS, here you go.
Note: I modified your tags to conform to the JS below. Also try to stay away from writing any inline scripts. Always good to keep your HTML and JS loosely coupled.
var fileTag = document.getElementById("filetag"),
preview = document.getElementById("preview");
fileTag.addEventListener("change", function() {
changeImage(this);
});
function changeImage(input) {
var reader;
if (input.files && input.files[0]) {
reader = new FileReader();
reader.onload = function(e) {
preview.setAttribute('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
<input type="file" id="filetag">
<img src="" id="preview">
You can also use the Image() constructor. It creates a new HTML Image Element.
Example -
document.getElementById("filetag").addEventListener("change", function(e) {
let newImg = new Image(width, height);
// Equivalent to above -> let newImg = document.createElement("img");
newImg.src = e.target.files[0];
newImg.src = URL.createObjectURL(e.target.files[0]);
output.appendChild(newImg);
});
Reference - https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image
You need one input tag to upload file and a image tag to render on the site.
The HTML and Javascript should look like
const renderFile = () => {
const render = document.querySelector('img')
const file = document.querySelector('input[type=file]').files[0]
const reader = new FileReader();
reader.addEventListener('load' , ()=> {
render.src = reader.result;
}, false)
if(file){
reader.readAsDataURL(file);
}
}
<input type = 'file' onchange = 'renderFile()' >
<br>
<br>
<img src = "" alt='rendered image' id='rendered-image' >
Simply on every upload the web page will show the image uploaded
You can Style the height and width of the image according to the need
I am trying to use jquery to take a picture from my comp via a form.
- So I want the entire URL out of the form in an array
It works + / - in Dreamweaver, but not in the explorer browsers not even chrome
The end goal is a calendar with picture / app for people with disabilities, but as long as I get to go through the phone gap
var foto= new Array();
var i=-1;
//foto=["toets.png"];
$('#fotouit').append("FOTO UIT");
$('#knop01').click(function(){
$('input:file[name=foto]').each(function(){
//alert($(this).val());
foto.push($(this).val());
foto.forEach( function(){
i++;
$('#fotouit').append(foto[i]);
$('#fotouit').append('<img src=" '+ foto[i] + ' " width="100" height="100" />');
});
});
})
I don't think it is possible to get the URL of the picture in you computer's local filesystem, but you can use Javascript's FileReader API to read the contents of the uploaded file (in your case, the picture). The read contents can be used in the src of the img element as you did in your example code.
This is an in depth explanation of what you're trying to accomplish: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
Example:
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /image.*/;
if (!file.type.match(imageType)) {
continue;
}
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
preview.appendChild(img); // Assuming that "preview" is a the div output where the content will be displayed.
var reader = new FileReader();
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
}
}
Note:
You can use the multiple attribute on a file input to allow selecting many files with one input
You can use the file inputs change event to immediately capture the files rather than providing a second button to click