Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the height and width of an image in Angular 2(or above) from input tag before uploading it to the server without jQuery?

I checked various sources but most of the solutions are in jQuery. I want the solution in Typescript if possible.

HTML -

<input #coverFilesInput class="file-input" type="file"(change)="onChange($event)"....>

Typescript -

onChange($event) { let img = event.target.files[0]; // and then I need code to validate image size }

Is there a solution or am I doing it completely wrong?

like image 613
vjmix Avatar asked May 28 '18 12:05

vjmix


2 Answers

You can use the combination of @ViewChild and ElementRef to access the file upload control and clear it's value after every upload otherwise the (change) event would not fire.

And then you can use FileReader() to read the file into an Image object and get the width and height from it.

Here is the code below -

HTML template

<input type="file" #coverFilesInput (change)="onChange($event)" class="file-input"  />
    Upload Percent: {{percentDone}}% <br />

    <ng-container *ngIf="uploadSuccess">
      Upload Successful of file with size : {{size}} bytes <br>
      The image height is : {{height}} <br>
      The image width is : {{width}} <br>
    </ng-container> 

The onChange method

onChange(evt:any){
   this.percentDone = 100;
   this.uploadSuccess = true;
   let image:any = evt.target.files[0];
   this.size = image.size;
   let fr = new FileReader();
   fr.onload = () => { // when file has loaded
    var img = new Image();
    img.onload = () => {
        this.width = img.width;
        this.height = img.height;
    };

    img.src = fr.result; // The data URL 
};

  fr.readAsDataURL(image);
   this.imgType.nativeElement.value = ""; // clear the value after upload
  }

complete code app.component.ts

import { Component, VERSION ,ViewChild,ElementRef} from '@angular/core';
import {HttpClientModule, HttpClient, HttpRequest, HttpResponse, HttpEventType} from '@angular/common/http';

@Component({
  selector: 'my-app',
  template: `
    Version = {{version.full}} <br/>
    <input type="file" #coverFilesInput (change)="onChange($event)" class="file-input"  />
    Upload Percent: {{percentDone}}% <br />

    <ng-container *ngIf="uploadSuccess">
      Upload Successful of file with size : {{size}} bytes <br>
      The image height is : {{height}} <br>
      The image width is : {{width}} <br>
    </ng-container> 
  `,
})
export class AppComponent {
  percentDone: number;
  uploadSuccess: boolean;
  size:any;
  width:number;
  height:number;

  @ViewChild('coverFilesInput') imgType:ElementRef;

  constructor(
    ) { }

  version = VERSION

  onChange(evt:any){
   this.percentDone = 100;
   this.uploadSuccess = true;
   let image:any = evt.target.files[0];
   this.size = image.size;
   let fr = new FileReader();
   fr.onload = () => { // when file has loaded
    var img = new Image();

    img.onload = () => {
        this.width = img.width;
        this.height = img.height;
    };

    img.src = fr.result; // This is the data URL 
   };

  fr.readAsDataURL(image);
   this.imgType.nativeElement.value = "";
  }  
}

Here is a working demo : https://stackblitz.com/edit/angular-file-upload-hnik7q

Edit : you can also use [(ngModel)]="selectedFile" to access the input file control and clear it's value after the validation and upload is done without using @ViewChild and ElementRef like below -

<input type="file" #coverFilesInput (change)="onChange($event)" class="file-input"  [(ngModel)]="selectedFile"/>

and in component class -

export class AppComponent {
  percentDone: number;
  uploadSuccess: boolean;
  size:any;
  width:number;
  height:number;
  selectedFile:any; // declare the property

  constructor(
    ) { }

  version = VERSION

  onChange(evt:any){
   this.percentDone = 100;
   this.uploadSuccess = true;
   let image:any = evt.target.files[0];
   this.size = image.size;
   let fr = new FileReader();
   fr.onload = () => { // when file has loaded
    var img = new Image();    
    img.onload = () => {
        this.width = img.width;
        this.height = img.height;
    };    
    img.src = fr.result; // This is the data URL 
};    
  fr.readAsDataURL(image);
  this.selectedFile = ""; // clear the file here
  }        
}
like image 60
Niladri Avatar answered Nov 07 '22 16:11

Niladri


Try this way, it's work for me!!

// in your .html file
<input type="file" class="form-control"
            accept="image/*" 
            (change)="onChange($event)">    

// in your .ts file
onChange(fileInput: any) {
    const URL = window.URL || window.webkitURL;
    const Img = new Image();

    const filesToUpload = (fileInput.target.files);
    Img.src = URL.createObjectURL(filesToUpload[0]);

    Img.onload = (e: any) => {
      const height = e.path[0].height;
      const width = e.path[0].width;

      console.log(height,width);
  }
}
like image 32
Cristian ventura Avatar answered Nov 07 '22 16:11

Cristian ventura