import sharp = require ( 'sharp' ) ; import config from '../config/main' ; import * as fs from 'fs' ; import * as path from 'path' ; import { BreakpointSize } from '../models/BreakpointSize' ; import { IResponsiveImageData } from '../../../shared/models/IResponsiveImageData' ; export default class ResponsiveImageService { param originalFile param { IResponsiveImageData } responsiveImage returns { Promise < boolean > } static async generateResponsiveImages ( originalFile , responsiveImage ) { if ( ! responsiveImage . breakpoints ) { return false ; } const filename = originalFile . filename ; const directory = originalFile . destination ; const extension = filename . split ( '.' ) . pop ( ) ; const filenameWithoutExtension = filename . substring ( 0 , filename . length - extension . length - 1 ) ; let keepOriginalFile = false ; for ( const breakpoint of responsiveImage . breakpoints ) { if ( breakpoint . screenSize === BreakpointSize . ORIGINAL ) { keepOriginalFile = false ; continue ; } const fileNameToSave = filenameWithoutExtension + '_' + breakpoint . screenSize + '.' + extension ; sharp . cache ( false ) ; const retinaFileNameToSave = filenameWithoutExtension + '_' + breakpoint . screenSize + '@2x.' + extension ; let resizeOptions = sharp ( originalFile . path ) ; let retinaResizeOptions = sharp ( originalFile . path ) ; if ( breakpoint . imageSize . width && breakpoint . imageSize . height ) { resizeOptions = resizeOptions . resize ( breakpoint . imageSize . width , breakpoint . imageSize . height , { fit : 'cover' , withoutEnlargement : true , position : sharp . gravity . center } ) ; retinaResizeOptions = retinaResizeOptions . resize ( breakpoint . imageSize . width * 2 , breakpoint . imageSize . height * 2 , { fit : 'cover' , withoutEnlargement : true , position : sharp . gravity . center } ) ; } else if ( ! breakpoint . imageSize . width && breakpoint . imageSize . height ) { resizeOptions = resizeOptions . resize ( null , breakpoint . imageSize . height , { fit : 'inside' , withoutEnlargement : true } ) ; retinaResizeOptions = retinaResizeOptions . resize ( null , breakpoint . imageSize . height * 2 , { fit : 'inside' , withoutEnlargement : true } ) ; } else { resizeOptions = resizeOptions . resize ( breakpoint . imageSize . width , null , { fit : 'inside' , withoutEnlargement : true } ) ; retinaResizeOptions = retinaResizeOptions . resize ( breakpoint . imageSize . width * 2 , null , { fit : 'inside' , withoutEnlargement : true } ) ; } await resizeOptions . toFile ( path . join ( directory , fileNameToSave ) ) ; await retinaResizeOptions . toFile ( path . join ( directory , retinaFileNameToSave ) ) ; const directoryRelative = path . relative ( path . dirname ( config . uploadFolder ) , directory ) . replace ( /\\\\?/g , '/' ) ; breakpoint . pathToImage = path . join ( directoryRelative , fileNameToSave ) ; breakpoint . pathToRetinaImage = path . join ( directoryRelative , retinaFileNameToSave ) ; } if ( ! keepOriginalFile ) { fs . unlinkSync ( originalFile . path ) ; responsiveImage . pathToImage = '-' ; } } }