@ -41,6 +41,45 @@ const dropOrientationIfNeeded = (orientation) => new Promise(resolve => {
}
}
} ) ;
} ) ;
// Some browsers don't allow reading from a canvas and instead return all-white
// or randomized data. Use a pre-defined image to check if reading the canvas
// works.
const checkCanvasReliability = ( ) => new Promise ( ( resolve , reject ) => {
switch ( _browser _quirks [ 'canvas-read-unreliable' ] ) {
case true :
reject ( 'Canvas reading unreliable' ) ;
break ;
case false :
resolve ( ) ;
break ;
default :
// 2×2 GIF with white, red, green and blue pixels
const testImageURL =
'data:image/gif;base64,R0lGODdhAgACAKEDAAAA//8AAAD/AP///ywAAAAAAgACAAACA1wEBQA7' ;
const refData =
[ 255 , 255 , 255 , 255 , 255 , 0 , 0 , 255 , 0 , 255 , 0 , 255 , 0 , 0 , 255 , 255 ] ;
const img = new Image ( ) ;
img . onload = ( ) => {
const canvas = document . createElement ( 'canvas' ) ;
const context = canvas . getContext ( '2d' ) ;
context . drawImage ( img , 0 , 0 , 2 , 2 ) ;
const imageData = context . getImageData ( 0 , 0 , 2 , 2 ) ;
if ( imageData . data . every ( ( x , i ) => refData [ i ] === x ) ) {
_browser _quirks [ 'canvas-read-unreliable' ] = false ;
resolve ( ) ;
} else {
_browser _quirks [ 'canvas-read-unreliable' ] = true ;
reject ( 'Canvas reading unreliable' ) ;
}
} ;
img . onerror = ( ) => {
_browser _quirks [ 'canvas-read-unreliable' ] = true ;
reject ( 'Failed to load test image' ) ;
} ;
img . src = testImageURL ;
}
} ) ;
const getImageUrl = inputFile => new Promise ( ( resolve , reject ) => {
const getImageUrl = inputFile => new Promise ( ( resolve , reject ) => {
if ( window . URL && URL . createObjectURL ) {
if ( window . URL && URL . createObjectURL ) {
try {
try {
@ -110,14 +149,6 @@ const processImage = (img, { width, height, orientation, type = 'image/png' }) =
context . drawImage ( img , 0 , 0 , width , height ) ;
context . drawImage ( img , 0 , 0 , width , height ) ;
// The Tor Browser and maybe other browsers may prevent reading from canvas
// and return an all-white image instead. Assume reading failed if the resized
// image is perfectly white.
const imageData = context . getImageData ( 0 , 0 , width , height ) ;
if ( imageData . data . every ( value => value === 255 ) ) {
throw 'Failed to read from canvas' ;
}
canvas . toBlob ( resolve , type ) ;
canvas . toBlob ( resolve , type ) ;
} ) ;
} ) ;
@ -127,7 +158,8 @@ const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) =
const newWidth = Math . round ( Math . sqrt ( MAX _IMAGE _PIXELS * ( width / height ) ) ) ;
const newWidth = Math . round ( Math . sqrt ( MAX _IMAGE _PIXELS * ( width / height ) ) ) ;
const newHeight = Math . round ( Math . sqrt ( MAX _IMAGE _PIXELS * ( height / width ) ) ) ;
const newHeight = Math . round ( Math . sqrt ( MAX _IMAGE _PIXELS * ( height / width ) ) ) ;
getOrientation ( img , type )
checkCanvasReliability ( )
. then ( getOrientation ( img , type ) )
. then ( orientation => processImage ( img , {
. then ( orientation => processImage ( img , {
width : newWidth ,
width : newWidth ,
height : newHeight ,
height : newHeight ,