package Ġorg . vide ol an . v lc . util ĊĊ Ċ import Ġandroid . graphics .* Ċ import Ġandroid . media . Thumbnail Utils Ċ import Ġandroid . net . Uri Ċ import Ġandroid . provider . Media Store Ċ import Ġandroid . util . Log Ċ import Ġandroidx . annotation . Worker Thread Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . Experimental Cor outines Api Ċ import Ġkotlinx . coroutines . Obsolete Cor outines Api Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġorg . vide ol an . med iali brary . interfaces . Med iali brary Ċ import Ġorg . vide ol an . med iali brary . interfaces . Med iali brary . MEDI AL IB _ FOLDER _ NAME Ċ import Ġorg . vide ol an . med iali brary . interfaces . media . Folder Ċ import Ġorg . vide ol an . med iali brary . interfaces . media . Media Wrapper Ċ import Ġorg . vide ol an . med iali brary . interfaces . media . Video Group Ċ import Ġorg . vide ol an . med iali brary . media . Media Library Item Ċ import Ġorg . vide ol an . resources . AppContext Provider Ċ import Ġorg . vide ol an . tools . Bitmap Cache Ċ import Ġorg . vide ol an . tools . Closeable Utils Ċ import Ġorg . vide ol an . tools . sanitize Path Ċ import Ġorg . vide ol an . v lc . Build Config Ċ import Ġorg . vide ol an . v lc . gui . helpers . Audio Util . read Cover Bitmap Ċ import Ġorg . vide ol an . v lc . gui . helpers . Bitmap Util Ċ import Ġorg . vide ol an . v lc . gui . helpers . Ui Tools Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . File Ċ import Ġjava . io . File OutputStream Ċ import Ġkotlin . math . min Ċ Ċ @ Experimental Cor outines Api Ċ @ Obsolete Cor outines Api Ċ object ĠThumb nails Provider Ġ{ ĊĊĠĠĠ Ġ@ Suppress (" unused ") ĊĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" VL C / Thumb nails Provider " ĊĊĠĠĠ Ġprivate Ġvar Ġapp Dir : ĠFile ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcache Dir : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ I MAGES Ġ= Ġ 4 ĊĠĠĠ Ġprivate Ġval Ġlock Ġ= ĠAny () ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġget Folder Thumbnail ( folder : ĠFolder , Ġwidth : ĠInt ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmedia Ġ= Ġfolder . media ( Folder . TYPE _ FOLDER _ VIDEO , ĠMed iali brary . SORT _ DEFAULT , Ġtrue , Ġ 4 , Ġ 0 ). filter NotNull () ĊĠĠĠĠĠĠĠ Ġreturn Ġget Comp osed Image (" folder :${ folder . m M rl . sanitize Path () }", Ġmedia , Ġwidth ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġget Video Group Thumbnail ( group : ĠVideo Group , Ġwidth : ĠInt ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmedia Ġ= Ġgroup . media ( Med iali brary . SORT _ DEFAULT , Ġtrue , Ġ 4 , Ġ 0 ). filter NotNull () ĊĠĠĠĠĠĠĠ Ġreturn Ġget Comp osed Image (" vide og roup :${ group . title }", Ġmedia , Ġwidth ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġget Media Thumbnail ( item : ĠMedia Wrapper , Ġwidth : ĠInt ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( is Media Video ( item )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Video Thumbnail ( item , Ġwidth ) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġread Cover Bitmap ( Uri . decode ( item . art work M rl ), Ġwidth ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Media Video ( item : ĠMedia Wrapper ) Ġ= Ġitem . type Ġ== ĠMedia Wrapper . TYPE _ VIDEO Ġ&& Ġitem . art work M rl . isNull OrEmpty () ĊĊĠĠĠ Ġprivate Ġfun Ġget Media Thumbnail Path ( is Media : ĠBoolean , Ġitem : ĠMedia Library Item ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Media Ġ&& Ġis Media Video ( item Ġas ĠMedia Wrapper )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( app Dir Ġ== Ġnull ) Ġapp Dir Ġ= ĠApp Context Provider . app Context . get External Files Dir ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhas Cache Ġ= Ġapp Dir Ġ!= Ġnull Ġ&& Ġapp Dir !!. exists () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Cache Ġ&& Ġcache Dir Ġ== Ġnull ) Ġcache Dir Ġ= Ġapp Dir !!. absolute Path Ġ+ ĠMED IAL IB _ FOLDER _ NAME ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( has Cache ) ĠStringBuilder ( cacheDir !! ). append ('/ '). append ( item . fileName ). append (". jpg "). toString () Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġitem . art work M rl ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Media CacheKey ( is Media : ĠBoolean , Ġitem : ĠMedia Library Item , Ġwidth : ĠString Ġ= Ġ"") Ġ= Ġif Ġ( width . isEmpty ()) Ġget Media Thumbnail Path ( is Media , Ġitem ) Ġelse Ġ"${ get Media Thumbnail Path ( is Media , Ġitem )} _$ width " ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġget Video Thumbnail ( media : ĠMedia Wrapper , Ġwidth : ĠInt ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠfilePath Ġ= Ġmedia . uri . path Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġif Ġ( app Dir Ġ== Ġnull ) Ġapp Dir Ġ= ĠApp Context Provider . app Context . get External Files Dir ( null ) ĊĠĠĠĠĠĠĠ Ġval Ġhas Cache Ġ= Ġapp Dir ?. exists () Ġ== Ġtrue ĊĠĠĠĠĠĠĠ Ġval Ġthumb Path Ġ= Ġget Media Thumbnail Path ( true , Ġmedia ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġcache BM Ġ= Ġif Ġ( has Cache ) ĠBitmap Cache . get Bitmap From Mem Cache ( get Media CacheKey ( true , Ġmedia )) Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġif Ġ( cache BM Ġ!= Ġnull ) Ġreturn Ġcache BM ĊĠĠĠĠĠĠĠ Ġif Ġ( has Cache Ġ&& ĠFile ( thumb Path ). exists ()) Ġreturn Ġread Cover Bitmap ( thumb Path , Ġwidth ) ĊĠĠĠĠĠĠĠ Ġif Ġ( media . is Thumbnail Generated ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġbitmap Ġ= Ġsynchronized ( lock ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠThumb nail Utils . create Video Thumbnail ( filePath , ĠMedia Store . Video . Thumb nails . MIN I _ KIND ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( bitmap Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġempty Bitmap Ġ= ĠBitmap . create Bitmap ( bitmap . width , Ġbitmap . height , Ġbitmap . config ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bitmap . same As ( empty Bitmap )) Ġ{ Ġ// Ġmy Bitmap Ġis Ġempty / blank 3 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( bitmap Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBitmap Cache . add Bitmap To Mem Cache ( thumb Path , Ġbitmap ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Cache ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia . set Thumbnail ( thumb Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave On Disk ( bitmap , Ġthumb Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia . art work URL Ġ= Ġthumb Path ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( media . id Ġ!= Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia . request Thumbnail ( width , Ġ 0 . 4 f ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġbitmap ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġget Playlist Image ( key : ĠString , Ġmedia List : ĠList < Media Wrapper >, Ġwidth : ĠInt , Ġicon Addition : ĠBitmap ? Ġ= Ġnull ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġto Ġforce Ġthe Ġthumbnail Ġre generation Ġon Ġchange , Ġwe Ġappend Ġthe Ġids Ġof Ġthe Ġmedia Ġthat Ġwill Ġbe Ġused Ġto Ġthe Ġcache Ġkey ĊĠĠĠĠĠĠĠ Ġval Ġsal ted Key Ġ= Ġkey Ġ+ Ġget Artwork List For Playlist ( media List ). join ToString ("_ ", Ġ": ") Ġ{ Ġit . id . toString () Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( Build Config . DEBUG ) ĠLog . d ( this :: class . java . simple Name , Ġ" Sal ted Ġkey Ġfrom Ġ$ key Ġis Ġ$ sal ted Key ") ĊĠĠĠĠĠĠĠ Ġreturn Ġ( Bitmap Cache . get Bitmap From Mem Cache ( sal ted Key ) Ġ?: Ġcompose Playlist Image ( media List , Ġwidth , Ġicon Addition )) ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBitmap Cache . add Bitmap To Mem Cache ( sal ted Key , Ġit ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRetrieve Ġthe Ġimages Ġto Ġbe Ġused Ġfor Ġthe Ġplaylist 's Ġthumbnail ĊĠĠĠĠ Ġ* Ġ@ param Ġmedia List Ġthe Ġmedia Ġlist Ġfor Ġthe Ġplaylist ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġsanit ied Ġlist Ġof Ġmedia Ġto Ġbe Ġused Ġfor Ġthe Ġplaylist Ġthumbnail Ġcomposition ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Artwork List For Playlist ( media List : ĠList < Media Wrapper >): ArrayList < Media Wrapper > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( media List . isEmpty ()) Ġreturn Ġarray ListOf () ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġmedia List [ 0 ]. art work URL ĊĠĠĠĠĠĠĠ Ġval Ġis All Same Image Ġ= Ġ! media List . any Ġ{ Ġit . art work URL Ġ!= Ġurl Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( is All Same Image ) Ġreturn Ġarray ListOf ( media List [ 0 ]) ĊĠĠĠĠĠĠĠ Ġval Ġart works Ġ= ĠArrayList < Media Wrapper >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( media Wrapper Ġin Ġmedia List ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġart work Already Here Ġ= Ġart works . any Ġ{ Ġit . art work URL Ġ== Ġmedia Wrapper . art work URL Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( media Wrapper . art work URL Ġ!= Ġnull Ġ&& Ġmedia Wrapper . art work URL . isNotBlank () Ġ&& Ġ! art work Already Here ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġart works . add ( media Wrapper ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( art works . size Ġ> Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( art works . size Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġart works . add ( art works [ 1 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġart works . add ( art works [ 0 ]) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( art works . size Ġ== Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġart works . add ( art works [ 0 ]) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġart works ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCompose Ġ 1 Ġimage Ġfrom Ġtracks Ġof Ġa ĠPlaylist ĊĠĠĠĠ Ġ* Ġ@ param Ġmedia List ĠThe Ġtrack Ġlist Ġof Ġthe Ġplaylist ĊĠĠĠĠ Ġ* Ġ@ return Ġa ĠBitmap Ġobject ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġcompose Playlist Image ( media List : ĠList < Media Wrapper >, Ġwidth : ĠInt , Ġicon Addition : ĠBitmap ?): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġart works Ġ= Ġget Artwork List For Playlist ( media List ) ĊĠĠĠĠĠĠĠ Ġif Ġ( art works . isEmpty ()) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġsame Image Ġ= Ġif Ġ( art works . size Ġ== Ġ 1 ) Ġobtain Bitmap ( media List [ 0 ], Ġwidth ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreturn Ġnull Ġelse Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġcs Ġ= ĠBitmap . create Bitmap ( width , Ġwidth , ĠBitmap . Config . ARGB _ 8 8 8 8 ) ĊĠĠĠĠĠĠĠ Ġval Ġcombo Image Ġ= ĠCanvas ( cs ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( same Image Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĠScale Ġthe Ġcover Ġart , Ġas Ġobtain Bitmap Ġmay Ġreturn Ġa Ġlarger Ġor Ġsmaller Ġimage Ġsize Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcombo Image . draw Bitmap ( same Image , ĠRect ( 0 , Ġ 0 , Ġsame Image . width , Ġsame Image . height ), ĠRect ( 0 , Ġ 0 , Ġwidth , Ġwidth ), Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimages Ġ= ĠArrayList < Bitmap >( 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġart works . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage Ġ= Ġobtain Bitmap ( it , Ġwidth Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( image Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimages . add ( image ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( images . size Ġ>= Ġ 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( images . size Ġ< Ġi Ġ+ Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimages . add ( Ui Tools . getDefault Audio Drawable ( AppContext Provider . app Context ). bitmap ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĠPlace Ġthe Ġfirst Ġimage Ġon Ġthe Ġdiagonal Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( images . size Ġ== Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimages . add ( images [ 0 ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcombo Image . draw Bitmap ( images [ 0 ], ĠRect ( 0 , Ġ 0 , Ġimages [ 0 ]. width , Ġimages [ 0 ]. height ), ĠRect ( 0 , Ġ 0 , Ġwidth Ġ/ Ġ 2 , Ġwidth Ġ/ Ġ 2 ), Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcombo Image . draw Bitmap ( images [ 1 ], ĠRect ( 0 , Ġ 0 , Ġimages [ 1 ]. width , Ġimages [ 1 ]. height ), ĠRect ( width Ġ/ Ġ 2 , Ġ 0 , Ġwidth , Ġwidth Ġ/ Ġ 2 ), Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcombo Image . draw Bitmap ( images [ 2 ], ĠRect ( 0 , Ġ 0 , Ġimages [ 2 ]. width , Ġimages [ 2 ]. height ), ĠRect ( 0 , Ġwidth Ġ/ Ġ 2 , Ġwidth Ġ/ Ġ 2 , Ġwidth ), Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcombo Image . draw Bitmap ( images [ 3 ], ĠRect ( 0 , Ġ 0 , Ġimages [ 3 ]. width , Ġimages [ 3 ]. height ), ĠRect ( width Ġ/ Ġ 2 , Ġwidth Ġ/ Ġ 2 , Ġwidth , Ġwidth ), Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġicon Addition ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcombo Image . draw Bitmap ( icon Addition , Ġ( combo Image . width . toFloat () Ġ- Ġicon Addition . width ) Ġ/ Ġ 2 , Ġ( combo Image . height . toFloat () Ġ- Ġicon Addition . height ) Ġ/ Ġ 2 , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcs ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġobtain Bitmap ( item : ĠMedia Library Item , Ġwidth : ĠInt ) Ġ= Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( item ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMedia Wrapper Ġ-> Ġget Media Thumbnail ( item , Ġwidth ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠFolder Ġ-> Ġget Folder Thumbnail ( item , Ġwidth ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠVideo Group Ġ-> Ġget Video Group Thumbnail ( item , Ġwidth ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġread Cover Bitmap ( Uri . decode ( item . art work M rl ), Ġwidth ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġfun Ġget Comp osed Image ( key : ĠString , Ġmedia List : ĠList < Media Wrapper >, Ġwidth : ĠInt ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcomposed Image Ġ= ĠBitmap Cache . get Bitmap From Mem Cache ( key ) ĊĠĠĠĠĠĠĠ Ġif Ġ( composed Image Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomposed Image Ġ= Ġcompose Image ( media List , Ġwidth ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( composed Image Ġ!= Ġnull ) ĠBitmap Cache . add Bitmap To Mem Cache ( key , Ġcomposed Image ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcomposed Image ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCompose Ġ 1 Ġimage Ġfrom Ġcombined Ġmedia Ġthumb nails ĊĠĠĠĠ Ġ* Ġ@ param Ġmedia List ĠThe Ġmedia Ġlist Ġfrom Ġwhich Ġwill Ġextract Ġthumb nails ĊĠĠĠĠ Ġ* Ġ@ return Ġa ĠBitmap Ġobject ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcompose Image ( media List : ĠList < Media Wrapper >, Ġimage Width : ĠInt ): ĠBitmap ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsources Images Ġ= ĠarrayOf Null s < Bitmap >( min ( MAX _ I MAGES , Ġmedia List . size )) ĊĠĠĠĠĠĠĠ Ġvar Ġcount Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar ĠminWidth Ġ= ĠInteger . MAX _ VALUE ĊĠĠĠĠĠĠĠ Ġvar ĠminHeight Ġ= ĠInteger . MAX _ VALUE ĊĠĠĠĠĠĠĠ Ġfor Ġ( media Ġin Ġmedia List ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbm Ġ= Ġget Video Thumbnail ( media , Ġimage Width ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bm Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwidth Ġ= Ġbm . width ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġheight Ġ= Ġbm . height ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsources Images [ count ++] Ġ= Ġbm ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠminWidth Ġ= Ġmin ( min Width , Ġwidth ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠminHeight Ġ= Ġmin ( min Height , Ġheight ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( count Ġ== ĠMAX _ I MAGES ) Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( count Ġ== Ġ 0 ) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( count Ġ== Ġ 1 ) Ġsources Images [ 0 ] Ġelse Ġcompose Canvas ( sources Images . filter NotNull (). to Typed Array (), Ġcount , ĠminWidth , ĠminHeight ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcompose Canvas ( sources Images : ĠArray < Bitmap >, Ġcount : ĠInt , ĠminWidth : ĠInt , ĠminHeight : ĠInt ): ĠBitmap Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoverlay Width : ĠInt ĊĠĠĠĠĠĠĠ Ġval Ġoverlay Height : ĠInt ĊĠĠĠĠĠĠĠ Ġwhen Ġ( count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 4 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverlay Width Ġ= Ġ 2 Ġ* ĠminWidth ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverlay Height Ġ= Ġ 2 Ġ* ĠminHeight ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverlay Width Ġ= ĠminWidth ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverlay Height Ġ= ĠminHeight ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġbm Overlay Ġ= ĠBitmap . create Bitmap ( overlay Width , Ġoverlay Height , Ġsources Images [ 0 ]. config ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcanvas Ġ= ĠCanvas ( bm Overlay ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 2 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġcount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsources Images [ i ] Ġ= ĠBitmap Util . center Crop ( sources Images [ i ], ĠminWidth Ġ/ Ġ 2 , ĠminHeight ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 0 ], Ġ 0 f , Ġ 0 f , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 1 ], Ġ( min Width Ġ/ Ġ 2 ). toFloat (), Ġ 0 f , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠ 3 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsources Images [ 0 ] Ġ= ĠBitmap Util . center Crop ( sources Images [ 0 ], ĠminWidth Ġ/ Ġ 2 , ĠminHeight Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsources Images [ 1 ] Ġ= ĠBitmap Util . center Crop ( sources Images [ 1 ], ĠminWidth Ġ/ Ġ 2 , ĠminHeight Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsources Images [ 2 ] Ġ= ĠBitmap Util . center Crop ( sources Images [ 2 ], ĠminWidth , ĠminHeight Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 0 ], Ġ 0 f , Ġ 0 f , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 1 ], Ġ( min Width Ġ/ Ġ 2 ). toFloat (), Ġ 0 f , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 2 ], Ġ 0 f , Ġ( min Height Ġ/ Ġ 2 ). toFloat (), Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠ 4 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġcount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsources Images [ i ] Ġ= ĠBitmap Util . center Crop ( sources Images [ i ], ĠminWidth , ĠminHeight ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 0 ], Ġ 0 f , Ġ 0 f , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 1 ], ĠminWidth . toFloat (), Ġ 0 f , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 2 ], Ġ 0 f , ĠminHeight . toFloat (), Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas . draw Bitmap ( sources Images [ 3 ], ĠminWidth . toFloat (), ĠminHeight . toFloat (), Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġbm Overlay ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsave On Disk ( bitmap : ĠBitmap , Ġdest Path : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstream Ġ= ĠByteArrayOutputStream () ĊĠĠĠĠĠĠĠ Ġbitmap . compress ( Bitmap . Compress Format . JPEG , Ġ 1 0 0 , Ġstream ) ĊĠĠĠĠĠĠĠ Ġval ĠbyteArray Ġ= Ġstream . toByteArray () ĊĠĠĠĠĠĠĠ Ġvar Ġf os : ĠFileOutputStream ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġf os Ġ= ĠFileOutputStream ( dest Path ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġf os . write ( byteArray ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : Ġjava . io . IOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠClose able Utils . close ( fos ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠClose able Utils . close ( stream ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ