mirror of
https://github.com/gedoor/legado.git
synced 2024-07-06 23:47:49 +08:00
Support svg
This commit is contained in:
parent
4631e6ea01
commit
139140f631
@ -220,6 +220,11 @@ dependencies {
|
||||
implementation("com.github.bumptech.glide:glide:$glideVersion")
|
||||
kapt("com.github.bumptech.glide:compiler:$glideVersion")
|
||||
|
||||
//Svg
|
||||
implementation("com.caverock:androidsvg-aar:1.4")
|
||||
//Glide svg plugin
|
||||
implementation("com.github.qoqa:glide-svg:4.0.2")
|
||||
|
||||
//webServer
|
||||
def nanoHttpdVersion = "2.3.1"
|
||||
implementation("org.nanohttpd:nanohttpd:$nanoHttpdVersion")
|
||||
|
@ -17,6 +17,7 @@ import io.legado.app.help.coroutine.Coroutine
|
||||
import io.legado.app.model.ReadBook
|
||||
import io.legado.app.model.localBook.EpubFile
|
||||
import io.legado.app.utils.BitmapUtils
|
||||
import io.legado.app.utils.SvgUtils
|
||||
import io.legado.app.utils.FileUtils
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
@ -55,8 +56,8 @@ object ImageProvider {
|
||||
if (oldBitmap != errorBitmap) {
|
||||
oldBitmap.recycle()
|
||||
triggerRecycled = true
|
||||
putDebug("ImageProvider: trigger bitmap recycle. URI: $filePath")
|
||||
putDebug("ImageProvider : cacheUsage ${size()}bytes / ${maxSize()}bytes")
|
||||
//putDebug("ImageProvider: trigger bitmap recycle. URI: $filePath")
|
||||
//putDebug("ImageProvider : cacheUsage ${size()}bytes / ${maxSize()}bytes")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,15 +98,16 @@ object ImageProvider {
|
||||
bookSource: BookSource?
|
||||
): Size {
|
||||
val file = cacheImage(book, src, bookSource)
|
||||
//svg size
|
||||
val size = SvgUtils.getSize(file.absolutePath)
|
||||
if (size != null) return size
|
||||
val op = BitmapFactory.Options()
|
||||
// inJustDecodeBounds如果设置为true,仅仅返回图片实际的宽和高,宽和高是赋值给opts.outWidth,opts.outHeight;
|
||||
op.inJustDecodeBounds = true
|
||||
BitmapFactory.decodeFile(file.absolutePath, op)
|
||||
if (op.outWidth < 1 && op.outHeight < 1) {
|
||||
Coroutine.async {
|
||||
putDebug("ImageProvider: delete file due to image size ${op.outHeight}*${op.outWidth}. path: ${file.absolutePath}")
|
||||
file.delete()
|
||||
}
|
||||
putDebug("ImageProvider: $src Unsupported image type")
|
||||
//file.delete() 重复下载
|
||||
return Size(errorBitmap.width, errorBitmap.height)
|
||||
}
|
||||
return Size(op.outWidth, op.outHeight)
|
||||
@ -135,6 +137,7 @@ object ImageProvider {
|
||||
if (height != null && AppConfig.asyncLoadImage && ReadBook.pageAnim() == PageAnim.scrollPageAnim) {
|
||||
Coroutine.async {
|
||||
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
||||
?: SvgUtils.createBitmap(vFile.absolutePath, width, height)
|
||||
?: throw NoStackTraceException(appCtx.getString(R.string.error_decode_bitmap))
|
||||
withContext(Main) {
|
||||
bitmapLruCache.put(vFile.absolutePath, bitmap)
|
||||
@ -142,10 +145,6 @@ object ImageProvider {
|
||||
}.onError {
|
||||
//错误图片占位,防止重复获取
|
||||
bitmapLruCache.put(vFile.absolutePath, errorBitmap)
|
||||
putDebug(
|
||||
"ImageProvider: decode bitmap failed. path: ${vFile.absolutePath}\n$it",
|
||||
it
|
||||
)
|
||||
}.onFinally {
|
||||
block?.invoke()
|
||||
}
|
||||
@ -154,16 +153,13 @@ object ImageProvider {
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
return kotlin.runCatching {
|
||||
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
||||
?: SvgUtils.createBitmap(vFile.absolutePath, width, height)
|
||||
?: throw NoStackTraceException(appCtx.getString(R.string.error_decode_bitmap))
|
||||
bitmapLruCache.put(vFile.absolutePath, bitmap)
|
||||
bitmap
|
||||
}.onFailure {
|
||||
//错误图片占位,防止重复获取
|
||||
bitmapLruCache.put(vFile.absolutePath, errorBitmap)
|
||||
putDebug(
|
||||
"ImageProvider: decode bitmap failed. path: ${vFile.absolutePath}\n$it",
|
||||
it
|
||||
)
|
||||
}.getOrDefault(errorBitmap)
|
||||
}
|
||||
|
||||
|
77
app/src/main/java/io/legado/app/utils/SvgUtils.kt
Normal file
77
app/src/main/java/io/legado/app/utils/SvgUtils.kt
Normal file
@ -0,0 +1,77 @@
|
||||
package io.legado.app.utils
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.PictureDrawable
|
||||
import android.util.Size
|
||||
import java.io.FileInputStream
|
||||
import java.io.InputStream
|
||||
import com.caverock.androidsvg.SVG
|
||||
import com.caverock.androidsvg.PreserveAspectRatio
|
||||
import com.caverock.androidsvg.SVGParseException
|
||||
import kotlin.math.max
|
||||
|
||||
@Suppress("WeakerAccess", "MemberVisibilityCanBePrivate")
|
||||
object SvgUtils {
|
||||
|
||||
/**
|
||||
* 从Svg中解码bitmap
|
||||
* https://github.com/qoqa/glide-svg/blob/master/library/src/main/java/ch/qoqa/glide/svg/SvgBitmapTranscoder.kt
|
||||
*/
|
||||
|
||||
fun createBitmap(filePath: String, width: Int, height: Int? = null): Bitmap? {
|
||||
val inputStream = FileInputStream(filePath)
|
||||
return createBitmap(inputStream, width, height)
|
||||
}
|
||||
|
||||
fun createBitmap(inputStream: InputStream, width: Int, height: Int? = null): Bitmap? {
|
||||
return kotlin.runCatching {
|
||||
val svg = SVG.getFromInputStream(inputStream)
|
||||
createBitmap(svg, width, height)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
//获取svg图片大小
|
||||
fun getSize(filePath: String): Size? {
|
||||
val inputStream = FileInputStream(filePath)
|
||||
return getSize(inputStream)
|
||||
}
|
||||
|
||||
fun getSize(inputStream: InputStream): Size? {
|
||||
return kotlin.runCatching {
|
||||
val svg = SVG.getFromInputStream(inputStream)
|
||||
getSize(svg)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
/////// private method
|
||||
private fun createBitmap(svg: SVG, width: Int, height: Int? = null): Bitmap {
|
||||
val size = getSize(svg)
|
||||
val wRatio = width.let { size.width / it } ?: -1
|
||||
val hRatio = height?.let { size.height / it } ?: -1
|
||||
//如果超出指定大小,则缩小相应的比例
|
||||
val ratio = when {
|
||||
wRatio > 1 && hRatio > 1 -> max(wRatio, hRatio)
|
||||
wRatio > 1 -> wRatio
|
||||
hRatio > 1 -> hRatio
|
||||
else -> 1
|
||||
}
|
||||
svg.documentPreserveAspectRatio = PreserveAspectRatio.START
|
||||
val picture = svg.renderToPicture(size.width / ratio, size.height / ratio)
|
||||
val drawable = PictureDrawable(picture)
|
||||
|
||||
val bitmap = Bitmap.createBitmap(size.width / ratio, size.height / ratio, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.drawPicture(drawable.picture)
|
||||
return bitmap
|
||||
}
|
||||
|
||||
private fun getSize(svg: SVG): Size {
|
||||
val width = svg.documentWidth.toInt().takeIf { it > 0 }
|
||||
?: (svg.documentViewBox.right - svg.documentViewBox.left).toInt()
|
||||
val height = svg.documentHeight.toInt().takeIf { it > 0 }
|
||||
?: (svg.documentViewBox.bottom - svg.documentViewBox.top).toInt()
|
||||
return Size(width, height)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user