try improving the image loading performance on weaker devices

This commit is contained in:
tibbi 2019-08-11 12:10:13 +02:00
parent f2b41a3758
commit a66596f160
3 changed files with 27 additions and 9 deletions

View File

@ -251,7 +251,6 @@ class PhotoFragment : ViewPagerFragment() {
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (!mWasInit) {
return
}
@ -272,6 +271,7 @@ class PhotoFragment : ViewPagerFragment() {
loadImage()
}
measureScreen()
initExtendedDetails()
updateInstantSwitchWidths()
}
@ -461,13 +461,14 @@ class PhotoFragment : ViewPagerFragment() {
mIsSubsamplingVisible = true
val config = context!!.config
val showHighestQuality = config.showHighestQuality
val minTileDpi = if (showHighestQuality) -1 else getMinTileDpi()
val bitmapDecoder = object : DecoderFactory<ImageDecoder> {
override fun make() = PicassoDecoder(mMedium.path, Picasso.get(), rotation)
}
val regionDecoder = object : DecoderFactory<ImageRegionDecoder> {
override fun make() = PicassoRegionDecoder(showHighestQuality)
override fun make() = PicassoRegionDecoder(showHighestQuality, mScreenWidth, mScreenHeight, minTileDpi)
}
var newOrientation = (rotation + mCurrentRotationDegrees) % 360
@ -477,7 +478,7 @@ class PhotoFragment : ViewPagerFragment() {
mView.subsampling_view.apply {
setMaxTileSize(if (showHighestQuality) Integer.MAX_VALUE else 4096)
setMinimumTileDpi(if (showHighestQuality) -1 else getMinTileDpi())
setMinimumTileDpi(minTileDpi)
background = ColorDrawable(Color.TRANSPARENT)
bitmapDecoderFactory = bitmapDecoder
regionDecoderFactory = regionDecoder
@ -487,6 +488,7 @@ class PhotoFragment : ViewPagerFragment() {
isOneToOneZoomEnabled = config.allowOneToOneZoom
orientation = newOrientation
setImage(mMedium.path)
onImageEventListener = object : SubsamplingScaleImageView.OnImageEventListener {
override fun onReady() {
background = ColorDrawable(if (config.blackBackground) Color.BLACK else config.backgroundColor)
@ -520,10 +522,10 @@ class PhotoFragment : ViewPagerFragment() {
val averageDpi = (metrics.xdpi + metrics.ydpi) / 2
val device = "${Build.BRAND} ${Build.MODEL}".toLowerCase()
return when {
WEIRD_DEVICES.contains(device) -> 240
averageDpi > 400 -> 280
averageDpi > 300 -> 220
else -> 160
WEIRD_DEVICES.contains(device) -> WEIRD_TILE_DPI
averageDpi > 400 -> HIGH_TILE_DPI
averageDpi > 300 -> NORMAL_TILE_DPI
else -> LOW_TILE_DPI
}
}

View File

@ -208,3 +208,9 @@ const val MAX_VIDEO_ZOOM_SCALE = 5f
const val ZOOM_MODE_NONE = 0
const val ZOOM_MODE_DRAG = 1
const val ZOOM_MODE_ZOOM = 2
// constants related to image quality
const val LOW_TILE_DPI = 160
const val NORMAL_TILE_DPI = 220
const val WEIRD_TILE_DPI = 240
const val HIGH_TILE_DPI = 280

View File

@ -5,7 +5,7 @@ import android.graphics.*
import android.net.Uri
import com.davemorrissey.labs.subscaleview.ImageRegionDecoder
class PicassoRegionDecoder(val showHighestQuality: Boolean) : ImageRegionDecoder {
class PicassoRegionDecoder(val showHighestQuality: Boolean, val screenWidth: Int, val screenHeight: Int, val minTileDpi: Int) : ImageRegionDecoder {
private var decoder: BitmapRegionDecoder? = null
private val decoderLock = Any()
@ -18,10 +18,20 @@ class PicassoRegionDecoder(val showHighestQuality: Boolean) : ImageRegionDecoder
override fun decodeRegion(rect: Rect, sampleSize: Int): Bitmap {
synchronized(decoderLock) {
var newSampleSize = sampleSize
if (!showHighestQuality && minTileDpi == LOW_TILE_DPI) {
if ((rect.width() > rect.height() && screenWidth > screenHeight) || (rect.height() > rect.width() && screenHeight > screenWidth)) {
if ((rect.width() / sampleSize > screenWidth || rect.height() / sampleSize > screenHeight)) {
newSampleSize *= 2
}
}
}
val options = BitmapFactory.Options()
options.inSampleSize = sampleSize
options.inSampleSize = newSampleSize
options.inPreferredConfig = if (showHighestQuality) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565
val bitmap = decoder!!.decodeRegion(rect, options)
return bitmap ?: throw RuntimeException("Region decoder returned null bitmap - image format may not be supported")
}
}