Skip to content

Instantly share code, notes, and snippets.

@anaibol
Forked from dcollien/ImageTools.es6
Last active November 8, 2016 10:31
Show Gist options
  • Save anaibol/058916c0e577683237a4afbc540b3fe4 to your computer and use it in GitHub Desktop.
Save anaibol/058916c0e577683237a4afbc540b3fe4 to your computer and use it in GitHub Desktop.
Resize Images in the Browser, returns a Promise
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