import * as path from 'path' ; import * as http from 'http' ; import * as https from 'https' ; import { parse as parseUrl } from 'url' ; import * as sizeOf from 'image-size' ; const reUrl = /^https?:/ ; /**
 * Get size of given image file. Supports files from local filesystem,
 * as well as URLs
 */ export function getImageSize ( file ) { file = file . replace ( /^file:\/\// , '' ) ; return reUrl . test ( file ) ? getImageSizeFromURL ( file ) : getImageSizeFromFile ( file ) ; } /**
 * Get image size from file on local file system
 */ function getImageSizeFromFile ( file ) { return new Promise ( ( resolve , reject ) => { const isDataUrl = file . match ( /^data:.+?;base64,/ ) ; if ( isDataUrl ) { try { const data = Buffer . from ( file . slice ( isDataUrl [ 0 ] . length ) , 'base64' ) ; return resolve ( sizeForFileName ( '' , sizeOf ( data ) ) ) ; } catch ( err ) { return reject ( err ) ; } } sizeOf ( file , ( err , size ) => { if ( err ) { reject ( err ) ; } else { resolve ( sizeForFileName ( path . basename ( file ) , size ) ) ; } } ) ; } ) ; } /**
 * Get image size from given remove URL
 */ function getImageSizeFromURL ( urlStr ) { return new Promise ( ( resolve , reject ) => { const url = parseUrl ( urlStr ) ; const getTransport = url . protocol === 'https:' ? https . get : http . get ; if ( ! url . pathname ) { return reject ( 'Given url doesnt have pathname property' ) ; } const urlPath = url . pathname ; getTransport ( url as any , resp => { const chunks = [ ] ; let bufSize = 0 ; const trySize = ( chunks ) => { try { const size = sizeOf ( Buffer . concat ( chunks , bufSize ) ) ; resp . removeListener ( 'data' , onData ) ; resp . destroy ( ) ; resolve ( sizeForFileName ( path . basename ( urlPath ) , size ) ) ; } catch ( err ) { } } ; const onData = ( chunk ) => { bufSize += chunk . length ; chunks . push ( chunk ) ; trySize ( chunks ) ; } ; resp . on ( 'data' , onData ) . on ( 'end' , ( ) => trySize ( chunks ) ) . once ( 'error' , err => { resp . removeListener ( 'data' , onData ) ; reject ( err ) ; } ) ; } ) . once ( 'error' , reject ) ; } ) ; } /**
 * Returns size object for given file name. If file name contains `@Nx` token,
 * the final dimentions will be downscaled by N
 */ function sizeForFileName ( fileName , size ) { const m = fileName . match ( /@(\d+)x\./ ) ; const scale = m ? + m [ 1 ] : 1 ; return { realWidth : size . width , realHeight : size . height , width : Math . floor ( size . width / scale ) , height : Math . floor ( size . height / scale ) } ; }