about summary refs log tree commit diff
path: root/app/javascript/mastodon/utils
diff options
context:
space:
mode:
authorYamagishi Kazutoshi <ykzts@desire.sh>2018-04-23 16:15:51 +0900
committerEugen Rochko <eugen@zeonfederated.com>2018-04-23 09:15:51 +0200
commit0758b00bfddf4a2c845d0d611e50717a268fd48a (patch)
treed196a207536dab549adb201b5f8201d8f38af8e1 /app/javascript/mastodon/utils
parent660cb058e18f8607a0044b5a89614e1caeb07ed9 (diff)
Refactor resizeImage method (#7236)
- Use URL.createObjectURL (replace from FileReader)
- Use HTMLCanvasElement.prototype.toBlob
  (replace from HTMLCanvasElement.prototype.toDataURL)
- Use Promise (replace callback interface)
Diffstat (limited to 'app/javascript/mastodon/utils')
-rw-r--r--app/javascript/mastodon/utils/__tests__/base64-test.js10
-rw-r--r--app/javascript/mastodon/utils/base64.js10
-rw-r--r--app/javascript/mastodon/utils/resize_image.js66
3 files changed, 86 insertions, 0 deletions
diff --git a/app/javascript/mastodon/utils/__tests__/base64-test.js b/app/javascript/mastodon/utils/__tests__/base64-test.js
new file mode 100644
index 000000000..1b3260faa
--- /dev/null
+++ b/app/javascript/mastodon/utils/__tests__/base64-test.js
@@ -0,0 +1,10 @@
+import * as base64 from '../base64';
+
+describe('base64', () => {
+  describe('decode', () => {
+    it('returns a uint8 array', () => {
+      const arr = base64.decode('dGVzdA==');
+      expect(arr).toEqual(new Uint8Array([116, 101, 115, 116]));
+    });
+  });
+});
diff --git a/app/javascript/mastodon/utils/base64.js b/app/javascript/mastodon/utils/base64.js
new file mode 100644
index 000000000..8226e2c54
--- /dev/null
+++ b/app/javascript/mastodon/utils/base64.js
@@ -0,0 +1,10 @@
+export const decode = base64 => {
+  const rawData = window.atob(base64);
+  const outputArray = new Uint8Array(rawData.length);
+
+  for (let i = 0; i < rawData.length; ++i) {
+    outputArray[i] = rawData.charCodeAt(i);
+  }
+
+  return outputArray;
+};
diff --git a/app/javascript/mastodon/utils/resize_image.js b/app/javascript/mastodon/utils/resize_image.js
new file mode 100644
index 000000000..6442eda38
--- /dev/null
+++ b/app/javascript/mastodon/utils/resize_image.js
@@ -0,0 +1,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);
+});