Fix tall image split math issues

- Round up per-split height to ensure the entire page ends up being split
- Handle the last split of a page potentially being shorter than the others
This commit is contained in:
arkon 2022-05-06 23:10:56 -04:00
parent a9e629aea6
commit 39c0b74250
4 changed files with 16 additions and 8 deletions

View file

@ -46,6 +46,8 @@ import java.io.FileOutputStream
import java.util.zip.CRC32
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import kotlin.math.ceil
import kotlin.math.min
/**
* This class is the one in charge of downloading chapters.
@ -569,25 +571,28 @@ class Downloader(
val bitmap = BitmapFactory.decodeFile(imageFile.filePath)
val splitsCount = bitmap.height / context.resources.displayMetrics.heightPixels + 1
val heightPerSplit = bitmap.height / splitsCount
val heightPerSplit = ceil(bitmap.height / splitsCount.toDouble()).toInt()
logcat { "Splitting height ${bitmap.height} by $splitsCount * $heightPerSplit" }
try {
(0..splitsCount).forEach { split ->
(0 until splitsCount).forEach { split ->
logcat { "Split #$split at y=${split * heightPerSplit}" }
val splitPath = imageFile.filePath!!.substringBeforeLast(".") + "__${"%03d".format(split + 1)}.jpg"
val splitHeight = split * heightPerSplit
FileOutputStream(splitPath).use { stream ->
Bitmap.createBitmap(
bitmap,
0,
split * heightPerSplit,
splitHeight,
bitmap.width,
heightPerSplit,
min(heightPerSplit, bitmap.height - splitHeight),
).compress(Bitmap.CompressFormat.JPEG, 100, stream)
}
}
imageFile.delete()
} catch (e: Exception) {
// Image splits were not successfully saved so delete them and keep the original image
(0..splitsCount)
(0 until splitsCount)
.map { imageFile.filePath!!.substringBeforeLast(".") + "__${"%03d".format(it + 1)}.jpg" }
.forEach { File(it).delete() }
throw e

View file

@ -19,6 +19,7 @@ import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import java.io.BufferedInputStream
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.util.concurrent.TimeUnit
@ -238,7 +239,7 @@ class PagerPageHolder(
.subscribe({}, {})
}
private fun process(page: ReaderPage, imageStream: InputStream): InputStream {
private fun process(page: ReaderPage, imageStream: BufferedInputStream): InputStream {
if (!viewer.config.dualPageSplit) {
return imageStream
}

View file

@ -23,6 +23,7 @@ import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import java.io.BufferedInputStream
import java.io.InputStream
import java.util.concurrent.TimeUnit
@ -272,7 +273,7 @@ class WebtoonPageHolder(
addSubscription(readImageHeaderSubscription)
}
private fun process(imageStream: InputStream): InputStream {
private fun process(imageStream: BufferedInputStream): InputStream {
if (!viewer.config.dualPageSplit) {
return imageStream
}

View file

@ -18,6 +18,7 @@ import androidx.core.graphics.green
import androidx.core.graphics.red
import tachiyomi.decoder.Format
import tachiyomi.decoder.ImageDecoder
import java.io.BufferedInputStream
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.InputStream
@ -103,7 +104,7 @@ object ImageUtil {
*
* @return true if the width is greater than the height
*/
fun isWideImage(imageStream: InputStream): Boolean {
fun isWideImage(imageStream: BufferedInputStream): Boolean {
val options = extractImageOptions(imageStream)
imageStream.reset()
return options.outWidth > options.outHeight