жовтень 9, 2016

Ресайз зображень у браузері

Щоб не міняти розмір картинок на сервері, їх розмір можна попередньо змінити в браузері клієнта.

Так ми економимо ресурси серверної частини, але не забудьте перевірити розміри надійшовшого файлу. Переконайтеся, що вам прийшла картинка і що у неї коректні розміри.

Функція для зміни і кропу картинки:

function resizeImage (src, resultWidth, resultHeight): Promise<string> {
  return new Promise<string>((resolve, reject) => {
    let canvas = document.createElement('canvas');
    let img = document.createElement('img');
    img.onload = function () {
      let imageWidth = img.width;
      let imageHeight = img.height;
      let imageCoef = imageWidth / imageHeight;
      let resultCoef = resultWidth / resultHeight;

      let sx = 0;
      let sy = 0;
      let swidth = imageWidth;
      let sheight = imageHeight;
      if (resultCoef < imageCoef) {
        swidth = sheight * resultCoef;
        sx = (imageWidth - swidth) / 2;
      }
      else {
        sheight = swidth * resultCoef;
        sy = (imageHeight - sheight) / 2;
      }

      canvas.width = resultWidth;
      canvas.height = resultHeight;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(img, sx, sy, swidth, sheight, 0, 0, resultWidth, resultHeight);

      resolve(canvas.toDataURL("image/png"));
    };
    img.src = src;
  });
}

Розмір картинки ми міняємо за допомогою <canvas>. Нормальний обріз картинки працює тільки для квадрату, інші комбінації я не тестував. Скоріш за всього потрібно буде трохи покрутити роботу коефіціентов.

Є ще одна особливість, після зменшення картинки немає згладжування, тому що пікселі просто "випадають". Якщо ви просто заливаєте аватарки або інші невеликі картинки, є просте рішення цієї проблеми: викликати функцію двічі і міняти розмір поетапно.

function pickPicture(event) {
  var reader = new FileReader();
  reader.onload = (e: any) => {
    resizeImage(e.target.result, 300, 300).then(pictureData => {
      resizeImage(pictureData, 150, 150).then(pictureData => {
        console.log('resized picture', pictureData);
      });
    });
  };
  reader.readAsDataURL(event.target.files[0]);
}

В даному прикладі мені потрібно отримати картинку 150px * 150px. Спочатку ми міняємо розмір до 300px * 300px, а потім згладжуємо її зміною розміру до потрібного. Важливо щоб проміжний розмір був у рази більше кінцевого результату.

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket