How to process image input to Angular app in an <img> element? - html

I am trying to create an Angular PWA that is able to take a picture, and after taking it to display it in an img element.
The first step I succeeded in: I now have an FAB button that opens the camera viewfinder (using the html input tag) with this small piece of code:
const element: HTMLElement = document.getElementById('imageCapturer') as HTMLElement;
element.click();
This simulates a click on the following HTML element:
<input type="file" accept="image/*" capture="environment" id="imageCapturer"">
However, after taking a picture I then want to use the image to render it in an img element (and also sending the image to a database with an API call)
I have tried multiple solutions including trying to add the file.name as src to the img element, and trying to create a new img HTML element with an attribute that uses the file. But I am still unable to process the image to be used in the img tag. Can somebody explain to me what the proper way to process the file is to be able to do this?
Cheers!

I solved this problem in the following way:
First, I changed the HTML to this:
<input type="file" accept="image/*" id="imageCapturer" style="display: none;" (change)="useImage($event)">
<img *ngIf="URL" [src]="URL" id="imageViewer">
Then the function useImage looks like this:
useImage(event) {
if (event.target.files && event.target.files[0]) {
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]); // Read file as data url
reader.onloadend = (e) => { // function call once readAsDataUrl is completed
this.URL = e.target['result']; // Set image in element
this._changeDetection.markForCheck(); // Is called because ChangeDetection is set to onPush
};
}
}
Now whenever a new image is captured or selected it is updated in the view

You can use event change of input file.
This example:
$('#imageCapturer').on('change', function () {
var input = $(this)[0];
if (input.files && input.files[0]) {
var fileName= input.files[0].name;
var reader = new FileReader();
reader.onload = function (e) {
var buffer = e.target.result;
var fileSize = input.files[0].size / 1024 / 1024; // in MB
// SET IMG DISPLAY
$('#image-display').attr('src', buffer).css({
'max-height': '170px',
'max-width': '170px',
};
reader.readAsDataURL(input.files[0]);
}
});
Note: You add more attribute [enctype="multipart/form-data"] in tag form when sumbit form it will send file byte[].
<form id="process_form" method="POST" enctype="multipart/form-data" autocomplete="off" role="form" data-parsley-focus="none">

Related

How to check for changes in file after it has been selected in a <input type="file">?

To upload I file in Angular, I am doing this:
<input type="file" (change)="onFileSelected($event.target.files)"/>
<button (click)="onStartUpload()"</button>
public onFileSelected(files: File[]) {
this.file = files[0];
}
public onStartUpload() {
// Upload the file
}
This works perfectly. But when I select a file, then change its content and save it, and then upload it, my backend response is this:
Unexpected end of Stream, the content may have already been read by
another component.
This only happens with Firefox. It works fine in Chrome.
Update: With Chrome's latest update, it does not send the request
anymore.
How can I check if the file has been changed after I selected it in the browser?
If you use an instance of the FileReader object, you can take advantage of the fact that it wont load a file that's been altered after having been selected. In order to upload the file successfully, it must remain the same as it was when it was chosen.
Here's a short example that will demonstrate. Tested on the current iteration of Chrome x64 under windows.
window.addEventListener('load', onLoaded, false);
function onLoaded(evt) {
document.querySelector('button').addEventListener('click', onBtnClicked, false);
}
function onBtnClicked(evt) {
let fileToUpload = document.querySelector('input').files[0];
const fileReader = new FileReader();
fileReader.onload = fileLoaded;
fileReader.onerror = fileError;
fileReader.readAsText(fileToUpload);
// fileReader.readAsArrayBuffer(fileToUpload);
// fileReader.readAsBinaryString(fileToUpload);
// fileReader.readAsDataURL(fileToUpload);
function fileLoaded(evt) {
let fileToUpload = evt.target.result;
}
function fileError(evt) {
console.log('Error loading file');
console.log(evt.target.error);
}
}
<input type='file' /><br>
<button>Go</button>

how to automatically open the camera

To capture the image from mobile using React js code, I am using the following code
<input type="file" accept="image/*" capture onChange={this.loadFile}/>
This input tag is dependent on the state variables in reacting. When the input tag gets rendered, firstly it will ask the user to click the "choose file "button and then will open the camera.
So, can we open the camera directly such that the "Choose File" button doesn't come and directly on changing the state values the camera gets open?
The loadFile handler function is :-
loadFile = (event: any) => {
var reader = new FileReader();
reader.onload = function() {
output: HTMLImageElement;
var output = document.getElementById("output");
output.src = reader.result;
};
reader.readAsDataURL(event.target.files[0]);
// console.log(event.target.files[0]);
this.setState({
activeCameraToggle: 0,
photo1: event.target.files[0]
});
};
Check this library:
https://github.com/react-community/react-native-image-picker
After adding it to your project do this:
// Launch Camera:
ImagePicker.launchCamera(options, (response) => {
// Same code as in above section!
});

How can you let a user change a picture in html?

I have an img src="example.jpg", and I also have an input type="file". I would like to know if there was a way to make the input type="file" change the img to whatever the user chooses off of his/her computer.
Here is a basic example with what you're asking, although it doesn't handle persistence, login sessions, or anything else you'll need for this to work in a production environment.
document.addEventListener('DOMContentLoaded', init);
function init() {
var input = document.querySelector('input');
var reader = new FileReader();
// When the FileReader "load" event fires, update the image.
reader.onload = function (e) {
document.getElementById("image").src = e.target.result;
};
// Listen for when the input changes.
input.addEventListener('change', onInputChange)
function onInputChange(e) {
reader.readAsDataURL(this.files[0]);
}
}
<img src="//placehold.it/200x200" id="image" height="200">
<input type="file">
Sidenote: Welcome to StackOverflow. You're getting downvotes as you're not including anything you've tried. SO is a place to get help with existing code, not to do research or write it for you.

rendering image for preview from selected file in file input tag

Now I have a form field:
<input id="my_img_field" type="file"/>
After I select the image in the browser, I want to render the selected image file on the target img tag:
<img id="image_preview" />
But I want to do this after the $('#my_img_field').change event, i.e. I may want this done when I click some button later.
I heard that this could be done using HTML5 technique. Can someone teach me how?
the code in vanilla js
var file = document.getElementById('my_img_field').files[0]
var fr = new FileReader()
fr.readAsDataURL(file)
fr.onload = function(e) {
var img = document.getElementById('image_preview')
img.src = this.result
}
The following approach will work:
var file = $('#my_img_field')[0].files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
var img = $('#image_preview');
img.attr('src', this.result);
}
It can be like this
const file = document.getElementById('my_img_field').files[0]
const link = window.URL.createObjectURL(file)

html5 drag and drop file uploads

I have a bunch of file uploads on my website and I was looking into making them into drag and drop fields. However I seem to be having an issue with them.
Is there any way to accomplish a drag and drop system without the use of javascript or plugins? I'm trying to make this as light as possible and with the least amount of code.
I have looked at several different methods of doing this such as http://html5demos.com/dnd-upload but they all include javascript.
At the moment I just have regular inputs that look like this
<input type="file" multiple="true" name="" value="" />
Afaik there is not a way to do this without the use of javascript. However, here is a simple example that does use javascript. If you drag an image over the red div it appends the image to the body. I've confirmed it works in IE11, Chrome 38, and Firefox 32. See the Html5Rocks article for a more detailed explanation.
<div id="dropZone" style="width: 100px; height: 100px; background-color: red"></div>
<script>
var dropZone = document.getElementById('dropZone');
// Optional. Show the copy icon when dragging over. Seems to only work for chrome.
dropZone.addEventListener('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
});
// Get file data on drop
dropZone.addEventListener('drop', function(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files; // Array of all files
for (var i=0, file; file=files[i]; i++) {
if (file.type.match(/image.*/)) {
var reader = new FileReader();
reader.onload = function(e2) {
var img = document.createElement('img');
img.src= e2.target.result;
document.body.appendChild(img);
}
reader.readAsDataURL(file);
} } });
</script>