about summary refs log tree commit diff
path: root/app/javascript/mastodon/utils/resize_image.js
blob: 6442eda38c3210996ab88ee3b84d72322b4ddd92 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const MAX_IMAGE_DIMENSION = 1280;

const getImageUrl = inputFile => new Promise((resolve, reject) => {
  if (window.URL && URL.createObjectURL) {
    try {
      resolve(URL.createObjectURL(inputFile));
    } catch (error) {
      reject(error);
    }
    return;
  }

  const reader = new FileReader();
  reader.onerror = (...args) => reject(...args);
  reader.onload  = ({ target }) => resolve(target.result);

  reader.readAsDataURL(inputFile);
});

const loadImage = inputFile => new Promise((resolve, reject) => {
  getImageUrl(inputFile).then(url => {
    const img = new Image();

    img.onerror = (...args) => reject(...args);
    img.onload  = () => resolve(img);

    img.src = url;
  }).catch(reject);
});

export default inputFile => new Promise((resolve, reject) => {
  if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') {
    resolve(inputFile);
    return;
  }

  loadImage(inputFile).then(img => {
    const canvas = document.createElement('canvas');
    const { width, height } = img;

    let newWidth, newHeight;

    if (width < MAX_IMAGE_DIMENSION && height < MAX_IMAGE_DIMENSION) {
      resolve(inputFile);
      return;
    }

    if (width > height) {
      newHeight = height * MAX_IMAGE_DIMENSION / width;
      newWidth  = MAX_IMAGE_DIMENSION;
    } else if (height > width) {
      newWidth  = width * MAX_IMAGE_DIMENSION / height;
      newHeight = MAX_IMAGE_DIMENSION;
    } else {
      newWidth  = MAX_IMAGE_DIMENSION;
      newHeight = MAX_IMAGE_DIMENSION;
    }

    canvas.width  = newWidth;
    canvas.height = newHeight;

    canvas.getContext('2d').drawImage(img, 0, 0, newWidth, newHeight);

    canvas.toBlob(resolve, inputFile.type);
  }).catch(reject);
});