-
-
Save anaibol/058916c0e577683237a4afbc540b3fe4 to your computer and use it in GitHub Desktop.
Resize Images in the Browser, returns a Promise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) { | |
return new Promise((resolve, reject) => { | |
let maxWidth = maxDimensions.width | |
let maxHeight = maxDimensions.height | |
if (!ImageTools.isSupported() || !file.type.match(/image.*/)) { | |
return resolve(file) | |
} | |
if (file.type.match(/image\/gif/)) { | |
// Not attempting, could be an animated gif | |
return resolve(file) | |
// TODO: use https://github.com/antimatter15/whammy to convert gif to webm | |
} | |
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) return resolve(file) | |
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 => resolve(blob), file.type) | |
} else { | |
return resolve(ImageTools._toBlob(canvas, file.type)) | |
} | |
} | |
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 | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment