diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 9861e288cb..deae549a57 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -110,8 +110,8 @@ class ReaderActivity : BaseRxActivity() { */ override fun onCreate(savedState: Bundle?) { setTheme(when (preferences.readerTheme().getOrDefault()) { - 0 -> R.style.Theme_Reader_Light - else -> R.style.Theme_Reader + 1 -> R.style.Theme_Reader + else -> R.style.Theme_Reader_Light }) super.onCreate(savedState) setContentView(R.layout.reader_activity) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index fc8dece8f0..eb68cd48cf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager import android.annotation.SuppressLint import android.content.Intent +import android.graphics.BitmapFactory import android.graphics.PointF import android.graphics.drawable.Drawable import android.net.Uri @@ -27,19 +28,19 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.github.chrisbanes.photoview.PhotoView import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.glide.GlideApp +import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressBar import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.ZoomType -import eu.kanade.tachiyomi.util.ImageUtil -import eu.kanade.tachiyomi.util.dpToPx -import eu.kanade.tachiyomi.util.gone -import eu.kanade.tachiyomi.util.visible +import eu.kanade.tachiyomi.util.* import eu.kanade.tachiyomi.widget.ViewPagerAdapter +import kotlinx.coroutines.experimental.async import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers +import uy.kohesive.injekt.injectLazy import java.io.InputStream import java.util.concurrent.TimeUnit @@ -99,6 +100,8 @@ class PagerPageHolder( */ private var readImageHeaderSubscription: Subscription? = null + private val preferences by injectLazy() + init { addView(progressBar) observeStatus() @@ -243,7 +246,22 @@ class PagerPageHolder( .observeOn(AndroidSchedulers.mainThread()) .doOnNext { isAnimated -> if (!isAnimated) { - initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!)) + if (preferences.readerTheme().get() == 2) { + val bytesArray = openStream!!.readBytes() + + val imageView = initSubsamplingImageView() + val bytesStream = bytesArray.inputStream() + imageView.setImage(ImageSource.inputStream(bytesStream)) + + launchUI { + val backgroundD = async { ImageUtil.autoSetBackground(BitmapFactory.decodeByteArray(bytesArray, 0, bytesArray.size)) } + imageView.background = backgroundD.await() + } + bytesStream.close() + } + else { + initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!)) + } } else { initImageView().setImage(openStream!!) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt index 9439953850..79b08b243d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsReaderController.kt @@ -49,8 +49,8 @@ class SettingsReaderController : SettingsController() { intListPreference { key = Keys.readerTheme titleRes = R.string.pref_reader_theme - entriesRes = arrayOf(R.string.white_background, R.string.black_background) - entryValues = arrayOf("0", "1") + entriesRes = arrayOf(R.string.white_background, R.string.black_background, R.string.auto_background) + entryValues = arrayOf("0", "1", "2") defaultValue = "0" summary = "%s" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt index fa879d4b4f..8a5814458f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt @@ -1,5 +1,8 @@ package eu.kanade.tachiyomi.util +import android.graphics.Bitmap +import android.graphics.Color +import android.graphics.drawable.* import java.io.InputStream import java.net.URLConnection @@ -49,6 +52,90 @@ object ImageUtil { return null } + fun autoSetBackground(image: Bitmap): Drawable { + if (image.width < 50 || image.height < 50) + return ColorDrawable(Color.WHITE) + val topLeftIsDark = isDark(image.getPixel(2,2)) + val topRightIsDark = isDark(image.getPixel(image.width - 2,2)) + val midLeftIsDark = isDark(image.getPixel(2,image.height/2)) + val midRightIsDark = isDark(image.getPixel(image.width - 2,image.height/2)) + val topMidIsDark = isDark(image.getPixel(image.width/2, 2)) + val botLeftIsDark = isDark(image.getPixel(2,image.height - 2)) + val botRightIsDark = isDark(image.getPixel(image.width - 2,image.height - 2)) + + var darkBG = (topLeftIsDark && (botLeftIsDark || botRightIsDark || topRightIsDark || midLeftIsDark || topMidIsDark)) + || (topRightIsDark && (botRightIsDark || botLeftIsDark || midRightIsDark || topMidIsDark)) + if (darkBG) { + if (isWhite(image.getPixel(2,2)).toInt() + + isWhite(image.getPixel(image.width - 2,2)).toInt() + + isWhite(image.getPixel(2,image.height - 2)).toInt() + + isWhite(image.getPixel(image.width - 2,image.height - 2)).toInt() > 2) + darkBG = false + var overallWhitePixels = 0 + var overallBlackPixels = 0 + outer@ for (x in intArrayOf(2,image.width-2)) { + var whitePixelsStreak = 0 + var whitePixels = 0 + var blackPixelsStreak = 0 + var blackPixels = 0 + var blackStreak = false + var whiteStrak = false + for (y in (0 until image.height step image.height / 25)) { + val pixel = image.getPixel(x, y) + if (isWhite(pixel)) { + blackPixelsStreak = 0 + whitePixelsStreak++ + whitePixels++ + overallWhitePixels++ + if (whitePixelsStreak > 14) { + whiteStrak = true + } + } + else { + whitePixelsStreak = 0 + if (isDark(pixel)) { + blackPixels++ + overallBlackPixels++ + blackPixelsStreak++ + if (blackPixelsStreak > 14) { + blackStreak = true + } + } + else { + blackPixelsStreak = 0 + } + } + } + when { + blackPixels > 22 -> return ColorDrawable(Color.BLACK) + blackStreak -> darkBG = true + whiteStrak || whitePixels > 22 -> darkBG = false + } + } + if (overallWhitePixels > 9 && overallWhitePixels >= overallBlackPixels) + darkBG = false + } + if (darkBG) + { + if (isWhite(image.getPixel(2,image.height - 2)) && isWhite(image.getPixel(image.width - 2,image.height - 2))) + return GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, + intArrayOf(Color.BLACK, Color.BLACK, Color.WHITE, Color.WHITE)) + else + return ColorDrawable(Color.BLACK) + } + return ColorDrawable(Color.WHITE) + } + + fun Boolean.toInt() = if (this) 1 else 0 + private fun isDark(color: Int): Boolean { + return Color.red(color) < 33 && Color.blue(color) < 33 && Color.green(color) < 33 + } + + + private fun isWhite(color: Int): Boolean { + return Color.red(color) + Color.blue(color) + Color.green(color) > 740 + } + private fun ByteArray.compareWith(magic: ByteArray): Boolean { for (i in 0 until magic.size) { if (this[i] != magic[i]) return false diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 9018a31f7c..ebdccc0d03 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -25,6 +25,7 @@ @string/white_background @string/black_background + @string/auto_background diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 73a073c77d..1bd4fc5a0d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -185,6 +185,7 @@ Background color White Black + Automatic Default viewer Default Left to right