mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
增加亮度和图片滤镜 (#4813)
Some checks are pending
Test Build / prepare (push) Waiting to run
Test Build / build (app, release) (push) Blocked by required conditions
Test Build / build (app, releaseA) (push) Blocked by required conditions
Test Build / prerelease (push) Blocked by required conditions
Test Build / lanzou (push) Blocked by required conditions
Test Build / test_Branch (push) Blocked by required conditions
Test Build / telegram (push) Blocked by required conditions
Some checks are pending
Test Build / prepare (push) Waiting to run
Test Build / build (app, release) (push) Blocked by required conditions
Test Build / build (app, releaseA) (push) Blocked by required conditions
Test Build / prerelease (push) Blocked by required conditions
Test Build / lanzou (push) Blocked by required conditions
Test Build / test_Branch (push) Blocked by required conditions
Test Build / telegram (push) Blocked by required conditions
* 增加亮度和图片滤镜 * ... * ... * ...
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
app/src/main/res/layout/dialog_manga_color_filter.xml
Normal file
116
app/src/main/res/layout/dialog_manga_color_filter.xml
Normal file
@@ -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>
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user