октябрь 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]);
}

В данном примере мне нужно получить картинку 150px150px. Сначала мы меняем размер до 300px300px, а потом сглаживаем ее изменением размера до нужного. Важно чтобы промежуточный размер был в раза больше исходного.

Спасибо за внимание и приятного вам кодинга.

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