import * as Jimp from 'jimp' ; import IImageData from '../model/IImageData' ; import PixelImage from '../model/PixelImage' ; import GraphicMode from '../model/GraphicMode' ; import Pixels from '../model/Pixels' ; import Palette from '../model/Palette' ; enum ScaleMode { none = 'none' , fill = 'fill' } export default class JimpPreprocessor { public static async read ( filename , graphicMode , scaleMode ) { const jimpImage = await Jimp . read ( filename ) ; if ( scaleMode === ScaleMode . none ) { this . crop ( jimpImage , graphicMode ) ; } else if ( scaleMode === ScaleMode . fill ) { this . cropFill ( jimpImage , graphicMode ) ; } else { throw new Error ( `Unknown scale mode: ${ scaleMode }` ) ; } return jimpImage . bitmap ; } public static async write ( pixelImage , filename , palette ) { const image = await this . toJimpImage ( pixelImage , palette ) ; image . resize ( pixelImage . mode . width * pixelImage . mode . pixelWidth , pixelImage . mode . height * pixelImage . mode . pixelHeight , Jimp . RESIZE_NEAREST_NEIGHBOR ) ; return image . write ( filename ) ; } private static toJimpImage ( pixelImage , palette ) { return new Promise ( ( resolve , reject ) => { new Jimp ( pixelImage . mode . width , pixelImage . mode . height , ( err , image ) => { this . pokeToJimp ( image , pixelImage , palette ) ; if ( err ) reject ( err ) ; resolve ( image ) ; } ) ; } ) ; } private static pokeToJimp ( image , pixelImage , palette ) { for ( let y = 0 ; y < image . bitmap . height ; y += 1 ) { for ( let x = 0 ; x < image . bitmap . width ; x += 1 ) { let pixelValue ; if ( x < pixelImage . mode . fliBugSize ) { pixelValue = [ 0 , 0 , 0 , 0xff ] ; } else { const paletteIndex = pixelImage . peek ( x , y ) ; pixelValue = paletteIndex !== undefined ? palette . colors [ paletteIndex ] : Pixels . emptyPixel ; } Pixels . poke ( image . bitmap , x , y , pixelValue ) ; } } } private static crop ( jimpImage , graphicMode ) { if ( jimpImage . bitmap . width < graphicMode . width || jimpImage . bitmap . height < graphicMode . height ) { throw new Error ( `Image size (${ jimpImage . bitmap . width }x${ jimpImage . bitmap . height }) must be at least ${ graphicMode . width * graphicMode . pixelWidth }x${ graphicMode . height * graphicMode . pixelHeight }` ) ; } if ( graphicMode . pixelWidth !== 1 ) { jimpImage . resize ( jimpImage . bitmap . width / graphicMode . pixelWidth , jimpImage . bitmap . height , Jimp . RESIZE_NEAREST_NEIGHBOR ) ; } jimpImage . crop ( 0 , 0 , graphicMode . width , graphicMode . height ) ; } private static cropFill ( jimpImage , graphicMode ) { jimpImage . cover ( graphicMode . width * graphicMode . pixelWidth , graphicMode . height * graphicMode . pixelHeight ) ; jimpImage . resize ( graphicMode . width , graphicMode . height ) ; } }