Resizing images with javascript using canvas elements

前端 未结 1 1586
南笙
南笙 2020-12-12 02:03

I\'m having a hard time to understand how to work with canvas elements in JavaScript.

I\'m implementing a resize feature where user can resize image ins

相关标签:
1条回答
  • 2020-12-12 02:58

    You can resize an image also at the client-side. The example code below uses an image loaded from the user's local system, to run the example without need to worry about CORS issues. The snippet also stores the image as a Blob object, which can be posted to the server if needed.

    // Creates a canvas containing a resized image
    function resizeImage(img) {
      var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d'),
        oWidth = img.naturalWidth,
        oHeight = img.naturalHeight,
        ratio = oWidth / oHeight,
        width = (ratio > 1) ? Math.min(200, oWidth) : Math.min(100, oWidth),
        height = Math.round(width / ratio);
      canvas.width = width;
      canvas.height = height;
      canvas.className = 'temp-cnv';
      document.body.appendChild(canvas);
      ctx.drawImage(img, 0, 0, width, height);
      return canvas;
    }
    
    // Define UI elements
    var img = document.getElementById('img'),
      loadBut = document.getElementById('load'),
      resizeBut = document.getElementById('resize'),
      resizedImage; // This will be sent to the server
    
    // Creates a blob and attaches it to an image element
    resizeBut.addEventListener('click', function() {
      var canvas;
      if (img.src === 'https://stacksnippets.net/js') {
        return; // Quit, no image loaded
      }
      canvas = resizeImage(img);
      canvas.toBlob(function(blob) {
        img.src = URL.createObjectURL(blob);
        resizedImage = blob;
        canvas.parentElement.removeChild(canvas);
      }, 'image/jpeg', 0.99);
    });
    
    // Reads an image from the user's local system
    loadBut.addEventListener('change', function(e) {
      var file = new FileReader();
      file.addEventListener('load', function() {
        img.src = file.result;
      });
      file.readAsDataURL(e.target.files[0]);
    });
    .temp-cnv {
      display: none;
    }
    <input type="file" id="load">
    <button id="resize">Resize</button>
    <br>
    <img src="" id="img">

    resizeImage function creates a temporary canvas element, and calculates the dimensions for that canvas. Here the image is always shrinked, but you can implement your own resizing algorithms. img.naturalWidth/Height properties contain the original size of the image.

    When the size of the canvas has been correctly set, the image is drawn into the canvas, at this point the actual resizing happens. Then the canvas is returned to the caller, and assigned to the local canvas variable.

    Then a Blob object is created from the newly-created canvas. toBlob function takes a callback function, mime-type and an optional quality parameter (for JPEGs only) as arguments. The callback function attaches the canvas into the image, and stores the created Blob object to resizedImage variable for the further use, and finally removes the temporary canvas element.

    Good to read at MDN:

    ctx.drawImage method
    Blob object
    Canvas.toBlob method
    CORS enabled images

    If you're going to send the resized image to the server, you can create a FormData object, and append the image to that object. Then post the object to the server with AJAX. Something like this:

    var xhr = new XMLHttpRequest(),
        form = new FormData();
    form.append('imageBlob', resizedImage); // resizedImage is the Blob object created in the first snippet
    form.append('imageName', 'THE_NAME_OF_THE_IMAGE');
    xhr.addEventListener('load', function (data) {
        // AJAX response handler code
    });
    xhr.open('POST', 'THE_URL_TO_POST_TO');
    xhr.send(form);
    

    Notice, that the POST parameters (the FormData object in this case) are attached as an argument of xhr.send call.

    0 讨论(0)
提交回复
热议问题