Skip to content

Instantly share code, notes, and snippets.

@dcollien
Last active April 28, 2023 09:00
Show Gist options
  • Save dcollien/312bce1270a5f511bf4a to your computer and use it in GitHub Desktop.
Save dcollien/312bce1270a5f511bf4a to your computer and use it in GitHub Desktop.
Resize Images in the Browser
let hasBlobConstructor = typeof(Blob) !== 'undefined' && (function () {
try {
return Boolean(new Blob());
} catch (e) {
return false;
}
}());
let hasArrayBufferViewSupport = hasBlobConstructor && typeof(Uint8Array) !== 'undefined' && (function () {
try {
return new Blob([new Uint8Array(100)]).size === 100;
} catch (e) {
return false;
}
}());
let hasToBlobSupport = (typeof HTMLCanvasElement !== "undefined" ? HTMLCanvasElement.prototype.toBlob : false);
let hasBlobSupport = (hasToBlobSupport || (typeof Uint8Array !== 'undefined' && typeof ArrayBuffer !== 'undefined' && typeof atob !== 'undefined'));
let hasReaderSupport = (typeof FileReader !== 'undefined' || typeof URL !== 'undefined');
export default class ImageTools {
static resize(file, maxDimensions, callback) {
if (typeof maxDimensions === 'function') {
callback = maxDimensions;
maxDimensions = {
width: 640,
height: 480
};
}
let maxWidth = maxDimensions.width;
let maxHeight = maxDimensions.height;
if (!ImageTools.isSupported() || !file.type.match(/image.*/)) {
callback(file, false);
return false;
}
if (file.type.match(/image\/gif/)) {
// Not attempting, could be an animated gif
callback(file, false);
// TODO: use https://github.com/antimatter15/whammy to convert gif to webm
return false;
}
let image = document.createElement('img');
image.onload = (imgEvt) => {
let width = image.width;
let height = image.height;
let isTooLarge = false;
if (width >= height && width > maxDimensions.width) {
// width is the largest dimension, and it's too big.
height *= maxDimensions.width / width;
width = maxDimensions.width;
isTooLarge = true;
} else if (height > maxDimensions.height) {
// either width wasn't over-size or height is the largest dimension
// and the height is over-size
width *= maxDimensions.height / height;
height = maxDimensions.height;
isTooLarge = true;
}
if (!isTooLarge) {
// early exit; no need to resize
callback(file, false);
return;
}
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, width, height);
if (hasToBlobSupport) {
canvas.toBlob((blob) => {
callback(blob, true);
}, file.type);
} else {
let blob = ImageTools._toBlob(canvas, file.type);
callback(blob, true);
}
};
ImageTools._loadImage(image, file);
return true;
}
static _toBlob(canvas, type) {
let dataURI = canvas.toDataURL(type);
let dataURIParts = dataURI.split(',');
let byteString;
if (dataURIParts[0].indexOf('base64') >= 0) {
// Convert base64 to raw binary data held in a string:
byteString = atob(dataURIParts[1]);
} else {
// Convert base64/URLEncoded data component to raw binary data:
byteString = decodeURIComponent(dataURIParts[1]);
}
let arrayBuffer = new ArrayBuffer(byteString.length);
let intArray = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteString.length; i += 1) {
intArray[i] = byteString.charCodeAt(i);
}
let mimeString = dataURIParts[0].split(':')[1].split(';')[0];
let blob = null;
if (hasBlobConstructor) {
blob = new Blob(
[hasArrayBufferViewSupport ? intArray : arrayBuffer],
{type: mimeString}
);
} else {
let bb = new BlobBuilder();
bb.append(arrayBuffer);
blob = bb.getBlob(mimeString);
}
return blob;
}
static _loadImage(image, file, callback) {
if (typeof(URL) === 'undefined') {
let reader = new FileReader();
reader.onload = function(evt) {
image.src = evt.target.result;
if (callback) { callback(); }
}
reader.readAsDataURL(file);
} else {
image.src = URL.createObjectURL(file);
if (callback) { callback(); }
}
};
static isSupported() {
return (
(typeof(HTMLCanvasElement) !== 'undefined')
&& hasBlobSupport
&& hasReaderSupport
);
}
}
'use strict';
if (typeof exports === "undefined") {
var exports = {};
}
if (typeof module === "undefined") {
var module = {};
}
Object.defineProperty(exports, '__esModule', {
value: true
});
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var hasBlobConstructor = typeof Blob !== 'undefined' && (function () {
try {
return Boolean(new Blob());
} catch (e) {
return false;
}
})();
var hasArrayBufferViewSupport = hasBlobConstructor && typeof Uint8Array !== 'undefined' && (function () {
try {
return new Blob([new Uint8Array(100)]).size === 100;
} catch (e) {
return false;
}
})();
var hasToBlobSupport = typeof HTMLCanvasElement !== "undefined" ? HTMLCanvasElement.prototype.toBlob : false;
var hasBlobSupport = hasToBlobSupport || typeof Uint8Array !== 'undefined' && typeof ArrayBuffer !== 'undefined' && typeof atob !== 'undefined';
var hasReaderSupport = typeof FileReader !== 'undefined' || typeof URL !== 'undefined';
var ImageTools = (function () {
function ImageTools() {
_classCallCheck(this, ImageTools);
}
_createClass(ImageTools, null, [{
key: 'resize',
value: function resize(file, maxDimensions, callback) {
if (typeof maxDimensions === 'function') {
callback = maxDimensions;
maxDimensions = {
width: 640,
height: 480
};
}
var maxWidth = maxDimensions.width;
var maxHeight = maxDimensions.height;
if (!ImageTools.isSupported() || !file.type.match(/image.*/)) {
callback(file, false);
return false;
}
if (file.type.match(/image\/gif/)) {
// Not attempting, could be an animated gif
callback(file, false);
// TODO: use https://github.com/antimatter15/whammy to convert gif to webm
return false;
}
var image = document.createElement('img');
image.onload = function (imgEvt) {
var width = image.width;
var height = image.height;
var isTooLarge = false;
if (width > height && width > maxDimensions.width) {
// width is the largest dimension, and it's too big.
height *= maxDimensions.width / width;
width = maxDimensions.width;
isTooLarge = true;
} else if (height > maxDimensions.height) {
// either width wasn't over-size or height is the largest dimension
// and the height is over-size
width *= maxDimensions.height / height;
height = maxDimensions.height;
isTooLarge = true;
}
if (!isTooLarge) {
// early exit; no need to resize
callback(file, false);
return;
}
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, width, height);
if (hasToBlobSupport) {
canvas.toBlob(function (blob) {
callback(blob, true);
}, file.type);
} else {
var blob = ImageTools._toBlob(canvas, file.type);
callback(blob, true);
}
};
ImageTools._loadImage(image, file);
return true;
}
}, {
key: '_toBlob',
value: function _toBlob(canvas, type) {
var dataURI = canvas.toDataURL(type);
var dataURIParts = dataURI.split(',');
var byteString = undefined;
if (dataURIParts[0].indexOf('base64') >= 0) {
// Convert base64 to raw binary data held in a string:
byteString = atob(dataURIParts[1]);
} else {
// Convert base64/URLEncoded data component to raw binary data:
byteString = decodeURIComponent(dataURIParts[1]);
}
var arrayBuffer = new ArrayBuffer(byteString.length);
var intArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteString.length; i += 1) {
intArray[i] = byteString.charCodeAt(i);
}
var mimeString = dataURIParts[0].split(':')[1].split(';')[0];
var blob = null;
if (hasBlobConstructor) {
blob = new Blob([hasArrayBufferViewSupport ? intArray : arrayBuffer], { type: mimeString });
} else {
var bb = new BlobBuilder();
bb.append(arrayBuffer);
blob = bb.getBlob(mimeString);
}
return blob;
}
}, {
key: '_loadImage',
value: function _loadImage(image, file, callback) {
if (typeof URL === 'undefined') {
var reader = new FileReader();
reader.onload = function (evt) {
image.src = evt.target.result;
if (callback) {
callback();
}
};
reader.readAsDataURL(file);
} else {
image.src = URL.createObjectURL(file);
if (callback) {
callback();
}
}
}
}, {
key: 'isSupported',
value: function isSupported() {
return typeof HTMLCanvasElement !== 'undefined' && hasBlobSupport && hasReaderSupport;
}
}]);
return ImageTools;
})();
exports['default'] = ImageTools;
module.exports = exports['default'];
@dcollien
Copy link
Author

I'm just using this now: http://nodeca.github.io/pica/demo/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment