PagerPageHolder: Move chooseBackground call to IO thread (#5737)
* ImageUtil.chooseBackground: Use built-in decoder * PagerPageHolder: Move chooseBackground call to IO thread Also move stuffs and reuse image stream as bytes
This commit is contained in:
parent
da16110e1c
commit
11a8046c5f
2 changed files with 28 additions and 21 deletions
|
@ -37,6 +37,7 @@ import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
import rx.schedulers.Schedulers
|
import rx.schedulers.Schedulers
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
@ -258,31 +259,40 @@ class PagerPageHolder(
|
||||||
unsubscribeReadImageHeader()
|
unsubscribeReadImageHeader()
|
||||||
val streamFn = page.stream ?: return
|
val streamFn = page.stream ?: return
|
||||||
|
|
||||||
var openStream: InputStream? = null
|
|
||||||
readImageHeaderSubscription = Observable
|
readImageHeaderSubscription = Observable
|
||||||
.fromCallable {
|
.fromCallable {
|
||||||
val stream = streamFn().buffered(16)
|
val stream = streamFn().buffered(16)
|
||||||
openStream = process(item, stream)
|
val itemStream = process(item, stream)
|
||||||
|
try {
|
||||||
ImageUtil.isAnimatedAndSupported(stream)
|
val streamBytes = itemStream.readBytes()
|
||||||
|
val isAnimated = ImageUtil.isAnimatedAndSupported(stream)
|
||||||
|
val background = if (!isAnimated && viewer.config.automaticBackground) {
|
||||||
|
ByteArrayInputStream(streamBytes).use { bais ->
|
||||||
|
ImageUtil.chooseBackground(context, bais)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
Triple(streamBytes, isAnimated, background)
|
||||||
|
} finally {
|
||||||
|
stream.close()
|
||||||
|
itemStream.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnNext { isAnimated ->
|
.doOnNext { (streamBytes, isAnimated, background) ->
|
||||||
|
ByteArrayInputStream(streamBytes).use { bais ->
|
||||||
if (!isAnimated) {
|
if (!isAnimated) {
|
||||||
|
this.background = background
|
||||||
initSubsamplingImageView().apply {
|
initSubsamplingImageView().apply {
|
||||||
if (viewer.config.automaticBackground) {
|
setImage(ImageSource.inputStream(bais))
|
||||||
background = ImageUtil.chooseBackground(context, openStream!!)
|
|
||||||
}
|
|
||||||
setImage(ImageSource.inputStream(openStream!!))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
initImageView().setImage(openStream!!)
|
initImageView().setImage(bais)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Keep the Rx stream alive to close the input stream only when unsubscribed
|
|
||||||
.flatMap { Observable.never<Unit>() }
|
|
||||||
.doOnUnsubscribe { openStream?.close() }
|
|
||||||
.subscribe({}, {})
|
.subscribe({}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import androidx.core.graphics.green
|
||||||
import androidx.core.graphics.red
|
import androidx.core.graphics.red
|
||||||
import tachiyomi.decoder.Format
|
import tachiyomi.decoder.Format
|
||||||
import tachiyomi.decoder.ImageDecoder
|
import tachiyomi.decoder.ImageDecoder
|
||||||
import tachiyomi.decoder.ImageType
|
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
@ -181,11 +180,9 @@ object ImageUtil {
|
||||||
* Algorithm for determining what background to accompany a comic/manga page
|
* Algorithm for determining what background to accompany a comic/manga page
|
||||||
*/
|
*/
|
||||||
fun chooseBackground(context: Context, imageStream: InputStream): Drawable {
|
fun chooseBackground(context: Context, imageStream: InputStream): Drawable {
|
||||||
imageStream.mark(imageStream.available() + 1)
|
val decoder = ImageDecoder.newInstance(imageStream)
|
||||||
|
val image = decoder?.decode()
|
||||||
val image = BitmapFactory.decodeStream(imageStream)
|
decoder?.recycle()
|
||||||
|
|
||||||
imageStream.reset()
|
|
||||||
|
|
||||||
val whiteColor = Color.WHITE
|
val whiteColor = Color.WHITE
|
||||||
if (image == null) return ColorDrawable(whiteColor)
|
if (image == null) return ColorDrawable(whiteColor)
|
||||||
|
|
Reference in a new issue