package Ġcom . ad rena . k mp . upload Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . graphics .* Ċ import Ġandroid . net . Uri Ċ import Ġandroid . util . Log Ċ import Ġandroidx . ex if interface . media . Ex if Interface Ċ import Ġjava . io .* Ċ Ċ class ĠBitmap Utils Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ċ } Ċ Ċ @ Throws ( IOException :: class ) Ċ fun ĠBitmap Utils . Companion . compress Image ( ĊĠĠĠ Ġcontext : ĠContext , ĊĠĠĠ Ġuri : ĠUri , ĊĠĠĠ Ġreq Width : ĠFloat Ġ= Ġ 1 0 0 0 . 0 f , ĊĠĠĠ Ġreq Height : ĠFloat Ġ= Ġ 1 0 0 0 . 0 f , ĊĠĠĠ Ġcompress Format : ĠBitmap . Compress Format Ġ= ĠBitmap . Compress Format . JPEG , ĊĠĠĠ Ġquality : ĠInt Ġ= Ġ 1 0 0 , ĊĠĠĠ Ġdestination Path : ĠString Ċ ): ĠFile Ġ{ ĊĊĠĠĠ Ġvar Ġfile OutputStream : ĠFileOutputStream ? Ġ= Ġnull ĊĊĠĠĠ Ġval Ġfile Ġ= ĠFile ( destination Path ). parent File Ġ?: Ġthrow ĠThrowable (" File Ġis Ġempty ") ĊĊĠĠĠ Ġif Ġ(! file . exists ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġfile . mkdir s () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval ĠinputStream Ġ= ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . open InputStream ( uri ) Ġ?: Ġthrow ĠThrowable (" Input Ġstream Ġis Ġempty ") ĊĊĠĠĠ Ġtry Ġ{ ĊĊĠĠĠĠĠĠĠ Ġfile OutputStream Ġ= ĠFileOutputStream ( destination Path ) ĊĠĠĠĠĠĠĠ Ġ// Ġwrite Ġthe Ġcompressed Ġbitmap Ġat Ġthe Ġdestination Ġspecified Ġby Ġdestination Path . ĊĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= Ġdecode Sample d Bitmap From InputStream ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuri , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreq Width , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreq Height ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġbitmap ?. compress ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcompress Format , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquality , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile OutputStream ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( file OutputStream Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile OutputStream . flush () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile OutputStream . close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ ĠinputStream . close () ĊĊĠĠĠ Ġreturn ĠFile ( destination Path ) Ċ } Ċ Ċ @ Throws ( IOException :: class ) Ċ private Ġfun Ġdecode Sample d Bitmap From InputStream ( ĊĠĠĠ Ġcontext : ĠContext , ĊĠĠĠ Ġuri : ĠUri , ĊĠĠĠ ĠinputStream : ĠInputStream , ĊĠĠĠ Ġreq Width : ĠFloat , ĊĠĠĠ Ġreq Height : ĠFloat Ċ ): ĠBitmap ? Ġ{ ĊĊĠĠĠ Ġ// ĠUsing Ġinput Ġstream Ġdirectly Ġto Ġget Ġorientation Ġwill Ġresult Ġnull Ġbitmap Ġwhen Ġdoing Ġdecode ByteArray ĊĠĠĠ Ġval Ġorientation Stream Ġ= ĊĠĠĠĠĠĠĠ Ġcontext . content Resolver . open InputStream ( uri ) Ġ?: Ġthrow ĠThrowable (" Input Ġstream Ġis Ġempty ") ĊĠĠĠ Ġval Ġorientation Ġ= Ġget Orientation ( orientation Stream ) ĊĠĠĠ Ġorientation Stream . close () ĊĊĠĠĠ Ġval ĠbyteArray Ġ= ĠinputStream . read Bytes () ĊĊĠĠĠ Ġvar Ġscaled Bitmap : ĠBitmap ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġbmp : ĠBitmap ? ĊĊĠĠĠ Ġval Ġoptions Ġ= ĠBitmap Factory . Options () ĊĊĠĠĠ Ġ// ĠFirst Ġdecode Ġwith Ġin Just Decode Bounds = true Ġto Ġcheck Ġdimensions ĊĠĠĠ Ġoptions . in Just Decode Bounds Ġ= Ġtrue ĊĊĠĠĠ Ġbmp Ġ= ĠBitmap Factory . decode ByteArray ( byteArray , Ġ 0 , ĠbyteArray . size , Ġoptions ) ĊĊĠĠĠ Ġvar Ġactual Height Ġ= Ġoptions . out Height ĊĠĠĠ Ġvar Ġactual Width Ġ= Ġoptions . out Width ĊĊĠĠĠ Ġvar Ġimg Ratio Ġ= Ġactual Width . toFloat () Ġ/ Ġactual Height . toFloat () ĊĠĠĠ Ġval Ġmax Ratio Ġ= Ġreq Width Ġ/ Ġreq Height ĊĊĠĠĠ Ġif Ġ( actual Height Ġ> Ġreq Height Ġ|| Ġactual Width Ġ> Ġreq Width ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// If ĠHeight Ġis Ġgreater ĊĠĠĠĠĠĠĠ Ġif Ġ( img Ratio Ġ< Ġmax Ratio ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimg Ratio Ġ= Ġreq Height Ġ/ Ġactual Height ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactual Width Ġ= Ġ( img Ratio Ġ* Ġactual Width ). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactual Height Ġ= Ġreq Height . toInt () ĊĊĠĠĠĠĠĠĠ Ġ} Ġ Ġ// If ĠWidth Ġis Ġgreater ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ( img Ratio Ġ> Ġmax Ratio ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimg Ratio Ġ= Ġreq Width Ġ/ Ġactual Width ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactual Height Ġ= Ġ( img Ratio Ġ* Ġactual Height ). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactual Width Ġ= Ġreq Width . toInt () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactual Height Ġ= Ġreq Height . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactual Width Ġ= Ġreq Width . toInt () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠCalculate Ġin Sample Size ĊĠĠĠ Ġoptions . in Sample Size Ġ= Ġcalculate In Sample Size ( ĊĠĠĠĠĠĠĠ Ġoptions , ĊĠĠĠĠĠĠĠ Ġactual Width , ĊĠĠĠĠĠĠĠ Ġactual Height ĊĠĠĠ Ġ) ĊĠĠĠ Ġoptions . in Just Decode Bounds Ġ= Ġfalse ĊĠĠĠ Ġoptions . in Temp Storage Ġ= ĠByteArray ( 1 6 Ġ* Ġ 1 0 2 4 ) ĊĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġbmp Ġ= ĠBitmap Factory . decode ByteArray ( byteArray , Ġ 0 , ĠbyteArray . size , Ġoptions ) ĊĠĠĠ Ġ} Ġcatch Ġ( exception : ĠOut Of Memory Error ) Ġ{ ĊĠĠĠĠĠĠĠ Ġexception . printStackTrace () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( bmp Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġscaled Bitmap Ġ= ĠBitmap . create Bitmap ( actual Width , Ġactual Height , ĠBitmap . Config . ARGB _ 8 8 8 8 ) ĊĠĠĠ Ġ} Ġcatch Ġ( exception : ĠOut Of Memory Error ) Ġ{ ĊĠĠĠĠĠĠĠ Ġexception . printStackTrace () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( scaled Bitmap Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġratio X Ġ= Ġactual Width Ġ/ Ġoptions . out Width . toFloat () ĊĠĠĠ Ġval Ġratio Y Ġ= Ġactual Height Ġ/ Ġoptions . out Height . toFloat () ĊĠĠĠ Ġval Ġmiddle X Ġ= Ġactual Width Ġ/ Ġ 2 . 0 f ĊĠĠĠ Ġval Ġmiddle Y Ġ= Ġactual Height Ġ/ Ġ 2 . 0 f ĊĊĠĠĠ Ġval Ġscale Matrix Ġ= ĠMatrix () ĊĠĠĠ Ġscale Matrix . set Scale ( ratio X , Ġratio Y , Ġmiddle X , Ġmiddle Y ) ĊĊĠĠĠ Ġval Ġcanvas Ġ= ĠCanvas ( scaled Bitmap ) ĊĠĠĠ Ġcanvas . set Matrix ( scale Matrix ) ĊĠĠĠ Ġcanvas . draw Bitmap ( ĊĠĠĠĠĠĠĠ Ġbmp , Ġmiddle X Ġ- Ġbmp . width Ġ/ Ġ 2 , ĊĠĠĠĠĠĠĠ Ġmiddle Y Ġ- Ġbmp . height Ġ/ Ġ 2 , ĠPaint ( Paint . FILTER _ BITMAP _ FLAG ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġbmp . recycle () ĊĊĠĠĠ Ġval Ġmatrix Ġ= ĠMatrix () ĊĊĠĠĠ Ġwhen Ġ( orientation ) Ġ{ ĊĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 9 0 Ġ-> Ġmatrix . post Rotate ( 9 0 F ) ĊĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 1 8 0 Ġ-> Ġmatrix . post Rotate ( 1 8 0 F ) ĊĠĠĠĠĠĠĠ ĠEx if Interface . OR IENTATION _ ROT ATE _ 2 7 0 Ġ-> Ġmatrix . post Rotate ( 2 7 0 F ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġscaled Bitmap Ġ= ĠBitmap . create Bitmap ( ĊĠĠĠĠĠĠĠ Ġscaled Bitmap , Ġ 0 , Ġ 0 , Ġscaled Bitmap . width , ĊĠĠĠĠĠĠĠ Ġscaled Bitmap . height , Ġmatrix , Ġtrue ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġreturn Ġscaled Bitmap Ċ } Ċ Ċ private Ġfun Ġcalculate In Sample Size ( ĊĠĠĠ Ġoptions : ĠBitmap Factory . Options , ĊĠĠĠ Ġreq Width : ĠInt , ĊĠĠĠ Ġreq Height : ĠInt Ċ ): ĠInt Ġ{ ĊĠĠĠ Ġ// ĠRaw Ġheight Ġand Ġwidth Ġof Ġimage ĊĠĠĠ Ġval Ġheight Ġ= Ġoptions . out Height ĊĠĠĠ Ġval Ġwidth Ġ= Ġoptions . out Width ĊĠĠĠ Ġvar Ġin Sample Size Ġ= Ġ 1 ĊĊĠĠĠ Ġif Ġ( height Ġ> Ġreq Height Ġ|| Ġwidth Ġ> Ġreq Width ) Ġ{ ĊĠĠĠĠĠĠĠ Ġin Sample Size Ġ*= Ġ 2 ĊĠĠĠĠĠĠĠ Ġval Ġhalf Height Ġ= Ġheight Ġ/ Ġ 2 ĊĠĠĠĠĠĠĠ Ġval Ġhalf Width Ġ= Ġwidth Ġ/ Ġ 2 ĊĊĠĠĠĠĠĠĠ Ġ// ĠCalculate Ġthe Ġlargest Ġin Sample Size Ġvalue Ġthat Ġis Ġa Ġpower Ġof Ġ 2 Ġand Ġkeeps Ġboth ĊĠĠĠĠĠĠĠ Ġ// Ġheight Ġand Ġwidth Ġlarger Ġthan Ġthe Ġrequested Ġheight Ġand Ġwidth . ĊĠĠĠĠĠĠĠ Ġwhile Ġ( half Height Ġ/ Ġin Sample Size Ġ>= Ġreq Height Ġ&& Ġhalf Width Ġ/ Ġin Sample Size Ġ>= Ġreq Width ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Sample Size Ġ*= Ġ 2 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġin Sample Size Ċ } Ċ Ċ private Ġfun Ġget Orientation ( inputStream : ĠInputStream ): ĠInt Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġex if Ġ= ĠEx if Interface ( inputStream ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġex if . getAttribute Int ( Ex if Interface . TAG _ OR IENTATION , ĠEx if Interface . OR IENTATION _ NORMAL ) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠThrowable ) Ġ{ ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠEx if Interface . OR IENTATION _ NORMAL Ċ }