diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 58f6d73fb..5ba2d0958 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -171,18 +171,19 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at book, textChar.charData, ReadBook.bookSource, - true - )?.let { + (textChar.end - textChar.start).toInt(), + (lineBottom - lineTop).toInt() + )?.let { bitmap -> val rectF = if (isImageLine) { RectF(textChar.start, lineTop, textChar.end, lineBottom) } else { /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ - val h = (textChar.end - textChar.start) / it.width * it.height + val h = (textChar.end - textChar.start) / bitmap.width * bitmap.height val div = (lineBottom - lineTop - h) / 2 RectF(textChar.start, lineTop + div, textChar.end, lineBottom - div) } kotlin.runCatching { - canvas.drawBitmap(it, null, rectF, null) + canvas.drawBitmap(bitmap, null, rectF, null) }.onFailure { e -> context.toastOnUi(e.localizedMessage) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index eeb2a5027..d8c821e6d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -101,7 +101,7 @@ object ChapterProvider { /** * 获取拆分完的章节数据 */ - fun getTextChapter( + suspend fun getTextChapter( book: Book, bookChapter: BookChapter, displayTitle: String, @@ -136,7 +136,6 @@ object ChapterProvider { while (matcher.find()) { matcher.group(1)?.let { src -> srcList.add(src) - ImageProvider.getImage(book, src, ReadBook.bookSource) matcher.appendReplacement(sb, srcReplaceChar) } } @@ -200,7 +199,7 @@ object ChapterProvider { ) } - private fun setTypeImage( + private suspend fun setTypeImage( book: Book, src: String, x: Int, @@ -209,7 +208,7 @@ object ChapterProvider { imageStyle: String?, ): Float { var durY = y - ImageProvider.getImage(book, src, ReadBook.bookSource)?.let { + ImageProvider.getImageSize(book, src, ReadBook.bookSource).let { if (durY > visibleHeight) { textPages.last().height = durY textPages.add(TextPage()) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index 2864158d8..877e190be 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -1,6 +1,8 @@ package io.legado.app.ui.book.read.page.provider import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.util.Size import io.legado.app.R import io.legado.app.constant.AppLog.putDebug import io.legado.app.data.entities.Book @@ -10,59 +12,108 @@ import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.glide.ImageLoader import io.legado.app.model.localBook.EpubFile import io.legado.app.utils.FileUtils -import io.legado.app.utils.BitmapUtils import io.legado.app.utils.isXml import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.suspendCancellableCoroutine import splitties.init.appCtx import java.io.File import java.io.FileOutputStream +import kotlin.coroutines.resume object ImageProvider { - private val errorBitmap: Bitmap? by lazy { - BitmapUtils.decodeBitmap( - appCtx, - R.drawable.image_loading_error, - ChapterProvider.visibleWidth, - ChapterProvider.visibleHeight - ) + private val errorBitmap: Bitmap by lazy { + BitmapFactory.decodeResource(appCtx.resources, R.drawable.image_loading_error) } - fun getImage( + private suspend fun cacheImage( book: Book, src: String, - bookSource: BookSource?, - onUi: Boolean = false, - ): Bitmap? { + bookSource: BookSource? + ): File { val vFile = BookHelp.getImage(book, src) if (!vFile.exists()) { if (book.isEpub()) { EpubFile.getImage(book, src)?.use { input -> val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath) + @Suppress("BlockingMethodInNonBlockingContext") FileOutputStream(newFile).use { output -> input.copyTo(output) } } - } else if (!onUi) { - runBlocking { - BookHelp.saveImage(bookSource, book, src) + } else { + BookHelp.saveImage(bookSource, book, src) + } + } + return vFile + } + + suspend fun getImageSize( + book: Book, + src: String, + bookSource: BookSource? + ): Size { + val file = cacheImage(book, src, bookSource) + return suspendCancellableCoroutine { block -> + kotlin.runCatching { + ImageLoader.loadBitmap(appCtx, file.absolutePath).submit() + .getSize { width, height -> + block.resume(Size(width, height)) + } + }.onFailure { + block.resume(Size(errorBitmap.width, errorBitmap.height)) + } + } + } + + fun getImage( + book: Book, + src: String, + bookSource: BookSource?, + width: Int, + height: Int + ): Bitmap? { + val vFile = runBlocking { + cacheImage(book, src, bookSource) + } + return try { + ImageLoader.loadBitmap(appCtx, vFile.absolutePath) + .submit(width, height) + .get() + } catch (e: Exception) { + Coroutine.async { + putDebug("${vFile.absolutePath} 解码失败", e) + if (FileUtils.readText(vFile.absolutePath).isXml()) { + putDebug("${vFile.absolutePath}为xml,自动删除") + vFile.delete() } } + errorBitmap + } + } + + fun getImage( + book: Book, + src: String, + bookSource: BookSource? + ): Bitmap? { + val vFile = runBlocking { + cacheImage(book, src, bookSource) } - return try { + return try { ImageLoader.loadBitmap(appCtx, vFile.absolutePath) - .submit(ChapterProvider.visibleWidth,ChapterProvider.visibleHeight) + .submit(ChapterProvider.visibleWidth, ChapterProvider.visibleHeight) .get() - } catch (e: Exception) { - Coroutine.async { - putDebug("${vFile.absolutePath} 解码失败", e) - if (FileUtils.readText(vFile.absolutePath).isXml()) { - putDebug("${vFile.absolutePath}为xml,自动删除") - vFile.delete() - } - } - errorBitmap - } + } catch (e: Exception) { + Coroutine.async { + putDebug("${vFile.absolutePath} 解码失败", e) + if (FileUtils.readText(vFile.absolutePath).isXml()) { + putDebug("${vFile.absolutePath}为xml,自动删除") + vFile.delete() + } + } + errorBitmap + } } }