Add an option to reencode images under the advanced tab. #262

This commit is contained in:
len 2016-04-21 15:31:07 +02:00
parent bd8b9febd2
commit 0a27d4e185
9 changed files with 50 additions and 7 deletions

View File

@ -7,7 +7,7 @@ import com.google.gson.reflect.TypeToken
import com.jakewharton.disklrucache.DiskLruCache import com.jakewharton.disklrucache.DiskLruCache
import eu.kanade.tachiyomi.data.source.model.Page import eu.kanade.tachiyomi.data.source.model.Page
import eu.kanade.tachiyomi.util.DiskUtils import eu.kanade.tachiyomi.util.DiskUtils
import eu.kanade.tachiyomi.util.saveTo import eu.kanade.tachiyomi.util.saveImageTo
import okhttp3.Response import okhttp3.Response
import okio.Okio import okio.Okio
import rx.Observable import rx.Observable
@ -185,7 +185,7 @@ class ChapterCache(private val context: Context) {
* @throws IOException image error. * @throws IOException image error.
*/ */
@Throws(IOException::class) @Throws(IOException::class)
fun putImageToCache(imageUrl: String, response: Response) { fun putImageToCache(imageUrl: String, response: Response, reencode: Boolean) {
// Initialize editor (edits the values for an entry). // Initialize editor (edits the values for an entry).
var editor: DiskLruCache.Editor? = null var editor: DiskLruCache.Editor? = null
@ -195,12 +195,10 @@ class ChapterCache(private val context: Context) {
editor = diskCache.edit(key) ?: throw IOException("Unable to edit key") editor = diskCache.edit(key) ?: throw IOException("Unable to edit key")
// Get OutputStream and write image with Okio. // Get OutputStream and write image with Okio.
response.body().source().saveTo(editor.newOutputStream(0)) response.body().source().saveImageTo(editor.newOutputStream(0), reencode)
diskCache.flush() diskCache.flush()
editor.commit() editor.commit()
} catch (e: Exception) {
throw IOException("Unable to save image")
} finally { } finally {
response.body().close() response.body().close()
editor?.abortUnlessCommitted() editor?.abortUnlessCommitted()

View File

@ -228,7 +228,14 @@ class DownloadManager(private val context: Context, private val sourceManager: S
page.status = Page.DOWNLOAD_IMAGE page.status = Page.DOWNLOAD_IMAGE
return source.getImageProgressResponse(page) return source.getImageProgressResponse(page)
.flatMap { .flatMap {
it.body().source().saveTo(File(directory, filename)) try {
val file = File(directory, filename)
file.parentFile.mkdirs()
it.body().source().saveImageTo(file.outputStream(), preferences.reencodeImage())
} catch (e: Exception) {
it.body().close()
throw e
}
Observable.just(page) Observable.just(page)
} }
.retry(2) .retry(2)

View File

@ -38,6 +38,8 @@ class PreferenceKeys(context: Context) {
val readWithVolumeKeys = context.getString(R.string.pref_read_with_volume_keys_key) val readWithVolumeKeys = context.getString(R.string.pref_read_with_volume_keys_key)
val reencodeImage = context.getString(R.string.pref_reencode_key)
val portraitColumns = context.getString(R.string.pref_library_columns_portrait_key) val portraitColumns = context.getString(R.string.pref_library_columns_portrait_key)
val landscapeColumns = context.getString(R.string.pref_library_columns_landscape_key) val landscapeColumns = context.getString(R.string.pref_library_columns_landscape_key)

View File

@ -78,6 +78,8 @@ class PreferencesHelper(private val context: Context) {
fun readWithVolumeKeys() = rxPrefs.getBoolean(keys.readWithVolumeKeys, false) fun readWithVolumeKeys() = rxPrefs.getBoolean(keys.readWithVolumeKeys, false)
fun reencodeImage() = prefs.getBoolean(keys.reencodeImage, false)
fun portraitColumns() = rxPrefs.getInteger(keys.portraitColumns, 0) fun portraitColumns() = rxPrefs.getInteger(keys.portraitColumns, 0)
fun landscapeColumns() = rxPrefs.getInteger(keys.landscapeColumns, 0) fun landscapeColumns() = rxPrefs.getInteger(keys.landscapeColumns, 0)

View File

@ -181,7 +181,7 @@ abstract class Source(context: Context) : BaseSource() {
page.status = Page.DOWNLOAD_IMAGE page.status = Page.DOWNLOAD_IMAGE
return getImageProgressResponse(page) return getImageProgressResponse(page)
.flatMap { resp -> .flatMap { resp ->
chapterCache.putImageToCache(page.imageUrl, resp) chapterCache.putImageToCache(page.imageUrl, resp, prefs.reencodeImage())
Observable.just(page) Observable.just(page)
} }
} }

View File

@ -1,5 +1,7 @@
package eu.kanade.tachiyomi.util package eu.kanade.tachiyomi.util
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import okio.BufferedSource import okio.BufferedSource
import okio.Okio import okio.Okio
import java.io.File import java.io.File
@ -37,3 +39,24 @@ fun BufferedSource.saveTo(stream: OutputStream) {
} }
} }
} }
/**
* Saves the given source to an output stream and closes both resources.
* The source is expected to be an image, and it may reencode the image.
*
* @param stream the stream where the source is copied.
* @param reencode whether to reencode the image or not.
*/
fun BufferedSource.saveImageTo(stream: OutputStream, reencode: Boolean = false) {
if (reencode) {
use {
val bitmap = BitmapFactory.decodeStream(it.inputStream())
stream.use {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
}
bitmap.recycle()
}
} else {
saveTo(stream)
}
}

View File

@ -33,6 +33,7 @@
<string name="pref_seamless_mode_key">pref_seamless_mode_key</string> <string name="pref_seamless_mode_key">pref_seamless_mode_key</string>
<string name="pref_read_with_volume_keys_key">reader_volume_keys</string> <string name="pref_read_with_volume_keys_key">reader_volume_keys</string>
<string name="pref_read_with_tapping_key">reader_tap</string> <string name="pref_read_with_tapping_key">reader_tap</string>
<string name="pref_reencode_key">reencode_image</string>
<string name="pref_filter_downloaded_key">pref_filter_downloaded_key</string> <string name="pref_filter_downloaded_key">pref_filter_downloaded_key</string>
<string name="pref_filter_unread_key">pref_filter_unread_key</string> <string name="pref_filter_unread_key">pref_filter_unread_key</string>

View File

@ -158,6 +158,10 @@
<string name="pref_clear_database">Clear database</string> <string name="pref_clear_database">Clear database</string>
<string name="pref_clear_database_summary">Delete manga and chapters that are not in your library</string> <string name="pref_clear_database_summary">Delete manga and chapters that are not in your library</string>
<string name="clear_database_confirmation">Are you sure? Read chapters and progress of non-library manga will be lost</string> <string name="clear_database_confirmation">Are you sure? Read chapters and progress of non-library manga will be lost</string>
<string name="pref_show_warning_message">Show warnings</string>
<string name="pref_show_warning_message_summary">Show warning messages during library sync </string>
<string name="pref_reencode">Reencode images</string>
<string name="pref_reencode_summary">Enable reencoding if images can\'t be decoded. Expect best results with Skia</string>
<!-- About section --> <!-- About section -->
<string name="version">Version</string> <string name="version">Version</string>

View File

@ -11,4 +11,10 @@
android:key="@string/pref_clear_database_key" android:key="@string/pref_clear_database_key"
android:summary="@string/pref_clear_database_summary"/> android:summary="@string/pref_clear_database_summary"/>
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="@string/pref_reencode_key"
android:summary="@string/pref_reencode_summary"
android:title="@string/pref_reencode"/>
</android.support.v7.preference.PreferenceScreen> </android.support.v7.preference.PreferenceScreen>