Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crop the image using JavaScript

In my Angular 6 application I am making a file upload option and in preview the uploaded file needs to be displayed with auto cropping and auto resizing.

I have tried the following,

HTML:

<canvas id="canvas"></canvas>
<div style="display:none;">
  <img id="source" [src]="url" width="300" height="227">
</div>
<input type='file' (change)="onSelectFile($event)">

File select functtion:

  onSelectFile(event) {
    if (event.target.files && event.target.files[0]) {
      var reader = new FileReader();

      reader.readAsDataURL(event.target.files[0]); // read file as data url

      reader.onload = (event) => { // called once readAsDataURL is completed
        this.url = event.target.result;
      }

      const canvas : any =  document.getElementById('canvas');
      const ctx = canvas.getContext('2d');
      const image = document.getElementById('source');

      ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
    }
  }

In the above I have tried the following with the reference of link https://jsfiddle.net/8jwq3cs7/

      const canvas : any =  document.getElementById('canvas');
      const ctx = canvas.getContext('2d');
      const image = document.getElementById('source');

      ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);

Before using the canvas the original image looks like this: https://mdn.mozillademos.org/files/5397/rhino.jpg

Whereas after using canvas it's like this: https://jsfiddle.net/8jwq3cs7/

But if I choose the image from choose file then I am unable to see the image after choosing...

Working example: https://stackblitz.com/edit/angular-file-upload-preview-uwpf8f

Even the solution with pure JavaScript alone would also be appreciable if not in the Angular way...

The requirement is, if I choose a file then the same file needs to be cropped and fit the size automatically in preview...

Kindly help me to achieve the result without jQuery or any library...

like image 780
Maniraj Murugan Avatar asked Dec 17 '18 07:12

Maniraj Murugan


People also ask

What is Cropperjs?

Cropper. js is a JavaScript library for cropping images in the browser. Now you are able to crop and use those cropped images in your Vaadin 14+ project with this custom add-on.


3 Answers

Here is a function to get the image as you are uploading using the choose file button

function readURL() {
    const myimg = document.getElementById("myimg");
    const input = document.getElementById("myfile");
    if(input.files && input.files[0]) {
        const reader = new FileReader();
        reader.onload = e => {
            console.log("changed");
            myimg.src = e.target.result;
        };
        reader.readAsDataURL(input.files[0]);
    }
}
document.querySelector('#myfile').addEventListener('change', () => {
    readURL();
});

And the HTML will be

<img src="" id="myimg"><br>
<input type="file" id="myfile">

Here is a working fiddle

If you add a file the preview image will be updated. You actually get a data url here. Use the data url to the load the image to the canvas then crop it. calling drawimg(e.target.result)

function drawimg(idata) {
    const img = new Image();
    img.onload = () => {
        ctx.drawImage(img, 33, 71, 104, 124, 21, 20, 87, 104);
    };
    img.src = idata;
}

See working Fiddle: here

like image 58
Geon George Avatar answered Oct 12 '22 14:10

Geon George


Here is how I implemented it in my case:

  onSelectFile(event) {
    if (event.target.files && event.target.files[0]) {
      var reader = new FileReader();

      reader.readAsDataURL(event.target.files[0]); // read file as data url

      reader.onload = (event) => { // called once readAsDataURL is completed
       console.log(event);
        this.url = event.target.result;
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        const image = new Image();
        image.src = this.url;

        ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);

      }

The working stackblitz demo is here : https://stackblitz.com/edit/angular-file-upload-preview-qrrgx5

Hope it helps and this is what you want.

like image 44
Black Mamba Avatar answered Oct 12 '22 13:10

Black Mamba


I'm a bit late to the party on this one, but I was facing a very similar issue myself yesterday, but instead using NodeJS.

My solution in the end was to break down the image into its RGBA values and check each row and column of the image to find where the image itself actually starts in comparison to the BG.

In my case, I'm working with images that are around 1500px*500px, with my solution taking around 150-250ms per image to read in the file, break down its pixels, calculate the cropping positions and to write the cropped file back to disk.

Since I couldn't find any nice libraries online to handle this, I've made my own and published it to NPM in case anyone else comes across the same issue and needs some help! :-)

https://www.npmjs.com/package/developyn-autocrop

like image 36
Melvyn Mathews Avatar answered Oct 12 '22 15:10

Melvyn Mathews