Просмотр исходного кода

增加亮度和图片滤镜 (#4813)

* 增加亮度和图片滤镜

* ...

* ...

* ...
lhjgege 1 год назад
Родитель
Сommit
2852c1f182

+ 1 - 0
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -100,6 +100,7 @@ object PreferKey {
     const val mangaFooterConfig = "mangaFooterConfig"
     const val disableClickScroll = "disableClickScroll"
     const val enableMangaHorizontalScroll = "enableMangaHorizontalScroll"
+    const val mangaColorFilter = "mangaColorFilter"
     const val autoRefresh = "auto_refresh"
     const val defaultToRead = "defaultToRead"
     const val exportCharset = "exportCharset"

+ 6 - 0
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -650,5 +650,11 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
         set(value) {
             appCtx.putPrefBoolean(PreferKey.enableMangaHorizontalScroll, value)
         }
+
+    var mangaColorFilter
+        get() = appCtx.getPrefString(PreferKey.mangaColorFilter, "")
+        set(value) {
+            appCtx.putPrefString(PreferKey.mangaColorFilter, value)
+        }
 }
 

+ 2 - 0
app/src/main/java/io/legado/app/model/ReadManga.kt

@@ -21,6 +21,7 @@ import io.legado.app.help.config.AppConfig
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.help.globalExecutor
 import io.legado.app.model.webBook.WebBook
+import io.legado.app.ui.book.manga.config.MangaColorFilterConfig
 import io.legado.app.ui.book.manga.entities.MangaChapter
 import io.legado.app.ui.book.manga.entities.MangaContent
 import io.legado.app.ui.book.manga.entities.MangaContentData
@@ -597,5 +598,6 @@ object ReadManga : CoroutineScope by MainScope() {
         fun loadFail(msg: String)
         fun sureNewProgress(progress: BookProgress)
         fun showLoading()
+        fun colorFilter(config: MangaColorFilterConfig)
     }
 }

+ 30 - 1
app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt

@@ -42,6 +42,8 @@ import io.legado.app.model.ReadManga
 import io.legado.app.receiver.NetworkChangedListener
 import io.legado.app.ui.book.changesource.ChangeBookSourceDialog
 import io.legado.app.ui.book.info.BookInfoActivity
+import io.legado.app.ui.book.manga.config.MangaColorFilterConfig
+import io.legado.app.ui.book.manga.config.MangaColorFilterDialog
 import io.legado.app.ui.book.manga.config.MangaFooterConfig
 import io.legado.app.ui.book.manga.config.MangaFooterSettingDialog
 import io.legado.app.ui.book.manga.entities.MangaContent
@@ -97,6 +99,11 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
         AppConfig.mangaAutoPageSpeed
     }
 
+    private val mMangaColorFilter: MangaColorFilterConfig by lazy {
+        GSON.fromJsonObject<MangaColorFilterConfig>(AppConfig.mangaColorFilter).getOrNull()
+            ?: MangaColorFilterConfig()
+    }
+
     private var mMangaAutoPageSpeed = mInitMangaAutoPageSpeed
     private lateinit var mMangaFooterConfig: MangaFooterConfig
     private val mLabelBuilder by lazy { StringBuilder() }
@@ -190,7 +197,10 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
     }
 
     private fun initRecyclerView() {
-        mAdapter.isHorizontal = AppConfig.enableMangaHorizontalScroll
+        mAdapter.run {
+            isHorizontal = AppConfig.enableMangaHorizontalScroll
+            setMangaImageColorFilter(mMangaColorFilter)
+        }
         binding.mRecyclerManga.run {
             adapter = mAdapter
             itemAnimator = null
@@ -418,6 +428,12 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
         }
     }
 
+    override fun colorFilter(config: MangaColorFilterConfig) {
+        mAdapter.setMangaImageColorFilter(config)
+        mAdapter.notifyItemChanged(ReadManga.durChapterPos)
+        updateWindowBrightness(config.l)
+    }
+
     override val oldBook: Book?
         get() = ReadManga.book
 
@@ -527,6 +543,10 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
                     mAdapter.getCurrentList().size
                 )
             }
+
+            R.id.menu_manga_color_filter -> {
+                MangaColorFilterDialog().show(supportFragmentManager, "MangaColorFilterDialog")
+            }
         }
         return super.onCompatOptionsItemSelected(item)
     }
@@ -717,4 +737,13 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
         return (mLayoutManager.findLastCompletelyVisibleItemPosition() == adapter.itemCount - 1) &&
                 !canScrollVertically(1)
     }
+
+    fun updateWindowBrightness(brightness: Int) {
+        val layoutParams = window.attributes
+        val normalizedBrightness = brightness.toFloat() / 255.0f
+        layoutParams.screenBrightness = normalizedBrightness.coerceIn(0f, 1f)
+        window.attributes = layoutParams
+        // 强制刷新屏幕
+        window.decorView.postInvalidate()
+    }
 }

+ 14 - 0
app/src/main/java/io/legado/app/ui/book/manga/config/MangaColorFilterConfig.kt

@@ -0,0 +1,14 @@
+package io.legado.app.ui.book.manga.config
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class MangaColorFilterConfig(
+    var r: Int = 0,
+    var g: Int = 0,
+    var b: Int = 0,
+    var a: Int = 0,
+    var l: Int = 0
+) :
+    Parcelable

+ 127 - 0
app/src/main/java/io/legado/app/ui/book/manga/config/MangaColorFilterDialog.kt

@@ -0,0 +1,127 @@
+package io.legado.app.ui.book.manga.config
+
+import android.content.DialogInterface
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.SeekBar
+import io.legado.app.R
+import io.legado.app.base.BaseDialogFragment
+import io.legado.app.databinding.DialogMangaColorFilterBinding
+import io.legado.app.help.config.AppConfig
+import io.legado.app.model.ReadManga
+import io.legado.app.utils.GSON
+import io.legado.app.utils.fromJsonObject
+import io.legado.app.utils.setLayout
+import io.legado.app.utils.viewbindingdelegate.viewBinding
+
+class MangaColorFilterDialog : BaseDialogFragment(R.layout.dialog_manga_color_filter) {
+    private val binding by viewBinding(DialogMangaColorFilterBinding::bind)
+    private val mConfig =
+        GSON.fromJsonObject<MangaColorFilterConfig>(AppConfig.mangaColorFilter).getOrNull()
+            ?: MangaColorFilterConfig()
+
+    override fun onStart() {
+        super.onStart()
+        setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+    }
+
+    override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
+        binding.seekA.progress = mConfig.a
+        binding.seekBrightness.progress = mConfig.l
+        binding.seekB.progress = mConfig.b
+        binding.seekG.progress = mConfig.g
+        binding.seekR.progress = mConfig.r
+        binding.seekBrightness.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+            override fun onProgressChanged(
+                seekBar: SeekBar?,
+                progress: Int,
+                fromUser: Boolean
+            ) {
+                mConfig.l = progress
+                ReadManga.mCallback?.colorFilter(mConfig)
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar?) {
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar?) {
+            }
+
+        })
+        binding.seekR.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+            override fun onProgressChanged(
+                seekBar: SeekBar?,
+                progress: Int,
+                fromUser: Boolean
+            ) {
+                mConfig.r = progress
+                ReadManga.mCallback?.colorFilter(mConfig)
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar?) {
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar?) {
+            }
+
+        })
+        binding.seekG.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+            override fun onProgressChanged(
+                seekBar: SeekBar?,
+                progress: Int,
+                fromUser: Boolean
+            ) {
+                mConfig.g = progress
+                ReadManga.mCallback?.colorFilter(mConfig)
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar?) {
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar?) {
+            }
+
+        })
+        binding.seekB.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+            override fun onProgressChanged(
+                seekBar: SeekBar?,
+                progress: Int,
+                fromUser: Boolean
+            ) {
+                mConfig.b = progress
+                ReadManga.mCallback?.colorFilter(mConfig)
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar?) {
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar?) {
+            }
+
+        })
+        binding.seekA.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+            override fun onProgressChanged(
+                seekBar: SeekBar?,
+                progress: Int,
+                fromUser: Boolean
+            ) {
+                mConfig.a = progress
+                ReadManga.mCallback?.colorFilter(mConfig)
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar?) {
+            }
+
+            override fun onStopTrackingTouch(seekBar: SeekBar?) {
+            }
+
+        })
+    }
+
+    override fun onDismiss(dialog: DialogInterface) {
+        super.onDismiss(dialog)
+        AppConfig.mangaColorFilter = GSON.toJson(mConfig)
+    }
+
+}

+ 24 - 0
app/src/main/java/io/legado/app/ui/book/manga/recyclerview/MangaAdapter.kt

@@ -1,6 +1,8 @@
 package io.legado.app.ui.book.manga.recyclerview
 
 import android.content.Context
+import android.graphics.ColorMatrix
+import android.graphics.ColorMatrixColorFilter
 import android.util.SparseArray
 import android.view.LayoutInflater
 import android.view.ViewGroup
@@ -22,6 +24,7 @@ import io.legado.app.databinding.BookComicRvBinding
 import io.legado.app.help.glide.progress.ProgressManager
 import io.legado.app.model.BookCover
 import io.legado.app.model.ReadManga
+import io.legado.app.ui.book.manga.config.MangaColorFilterConfig
 import io.legado.app.ui.book.manga.entities.MangaContent
 import io.legado.app.ui.book.manga.entities.ReaderLoading
 import io.legado.app.utils.getCompatDrawable
@@ -32,6 +35,7 @@ class MangaAdapter(private val context: Context) :
     RecyclerView.Adapter<RecyclerView.ViewHolder>(), PreloadModelProvider<Any> {
 
     private val inflater: LayoutInflater = LayoutInflater.from(context)
+    private lateinit var mConfig: MangaColorFilterConfig
 
     companion object {
         private const val LOADING_VIEW = 0
@@ -95,8 +99,24 @@ class MangaAdapter(private val context: Context) :
         }
 
         fun onBind(item: MangaContent) {
+            setImageColorFilter()
             loadImageWithRetry(item.mImageUrl, isHorizontal, item.imageCount == 1)
         }
+
+        fun setImageColorFilter() {
+            binding.image.run {
+                require(mConfig.r in 0..255 && mConfig.g in 0..255 && mConfig.b in 0..255 && mConfig.a in 0..255) {
+                    "ARGB values must be between 0-255"
+                }
+                val matrix = floatArrayOf(
+                    (255 - mConfig.r) / 255f, 0f, 0f, 0f, 0f,
+                    0f, (255 - mConfig.g) / 255f, 0f, 0f, 0f,
+                    0f, 0f, (255 - mConfig.b) / 255f, 0f, 0f,
+                    0f, 0f, 0f, (255 - mConfig.a) / 255f, 0f
+                )
+                colorFilter = ColorMatrixColorFilter(ColorMatrix(matrix))
+            }
+        }
     }
 
     inner class PageMoreViewHolder(val binding: BookComicLoadingRvBinding) :
@@ -209,4 +229,8 @@ class MangaAdapter(private val context: Context) :
         }
         return null
     }
+
+    fun setMangaImageColorFilter(config: MangaColorFilterConfig) {
+        mConfig = config
+    }
 }

+ 116 - 0
app/src/main/res/layout/dialog_manga_color_filter.xml

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="16dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <io.legado.app.ui.widget.text.AccentTextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="滤镜"
+            android:textSize="18sp" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="@string/brightness"
+            android:textColor="@color/primaryText"
+            android:textSize="14sp" />
+
+        <io.legado.app.lib.theme.view.ThemeSeekBar
+            android:id="@+id/seek_brightness"
+            android:layout_width="match_parent"
+            android:layout_height="25dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="4dp"
+            android:layout_marginEnd="16dp"
+            android:layout_weight="1"
+            android:max="255" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="R"
+            android:textColor="@color/primaryText"
+            android:textSize="14sp" />
+
+        <io.legado.app.lib.theme.view.ThemeSeekBar
+            android:id="@+id/seek_R"
+            android:layout_width="match_parent"
+            android:layout_height="25dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="4dp"
+            android:layout_marginEnd="16dp"
+            android:layout_weight="1"
+            android:max="255" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="G"
+            android:textColor="@color/primaryText"
+            android:textSize="14sp" />
+
+        <io.legado.app.lib.theme.view.ThemeSeekBar
+            android:id="@+id/seek_g"
+            android:layout_width="match_parent"
+            android:layout_height="25dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="4dp"
+            android:layout_marginEnd="16dp"
+            android:layout_weight="1"
+            android:max="255" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="B"
+            android:textColor="@color/primaryText"
+            android:textSize="14sp" />
+
+        <io.legado.app.lib.theme.view.ThemeSeekBar
+            android:id="@+id/seek_b"
+            android:layout_width="match_parent"
+            android:layout_height="25dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="4dp"
+            android:layout_marginEnd="16dp"
+            android:layout_weight="1"
+            android:max="255" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="A"
+            android:textColor="@color/primaryText"
+            android:textSize="14sp" />
+
+        <io.legado.app.lib.theme.view.ThemeSeekBar
+            android:id="@+id/seek_a"
+            android:layout_width="match_parent"
+            android:layout_height="25dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="4dp"
+            android:layout_marginEnd="16dp"
+            android:layout_weight="1"
+            android:max="255" />
+
+
+    </LinearLayout>
+
+</androidx.core.widget.NestedScrollView>

+ 2 - 1
app/src/main/res/layout/view_manga_menu.xml

@@ -19,7 +19,8 @@
         android:id="@+id/title_bar"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:theme="?attr/actionBarStyle">
+        android:theme="?attr/actionBarStyle"
+        app:layout_constraintTop_toTopOf="parent">
 
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/title_bar_addition"

+ 6 - 0
app/src/main/res/menu/book_manga.xml

@@ -68,4 +68,10 @@
         android:id="@+id/menu_manga_footer_config"
         android:title="@string/manga_footer_config"
         app:showAsAction="never" />
+
+    <item
+        android:id="@+id/menu_manga_color_filter"
+        android:title="@string/manga_color_filter"
+        app:showAsAction="never" />
+
 </menu>

+ 1 - 0
app/src/main/res/values-es-rES/strings.xml

@@ -1205,4 +1205,5 @@
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>

+ 1 - 0
app/src/main/res/values-ja-rJP/strings.xml

@@ -1208,4 +1208,5 @@
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>

+ 1 - 0
app/src/main/res/values-pt-rBR/strings.xml

@@ -1208,4 +1208,5 @@
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>

+ 1 - 0
app/src/main/res/values-vi/strings.xml

@@ -1204,4 +1204,5 @@ Còn </string>
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -1205,4 +1205,5 @@
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -1207,4 +1207,5 @@
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>

+ 1 - 0
app/src/main/res/values-zh/strings.xml

@@ -1207,4 +1207,5 @@
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -1208,4 +1208,5 @@
     <string name="manga_radio_left">靠左</string>
     <string name="manga_radio_center">居中</string>
     <string name="enable_manga_horizontal_scroll">水平滚动</string>
+    <string name="manga_color_filter">滤镜</string>
 </resources>