multipage: heic track tiling
This commit is contained in:
parent
c332e125bb
commit
b59b323d34
5 changed files with 73 additions and 17 deletions
|
@ -5,6 +5,9 @@ import android.graphics.Rect
|
|||
import android.net.Uri
|
||||
import android.util.Size
|
||||
import com.bumptech.glide.Glide
|
||||
import deckers.thibault.aves.channel.calls.fetchers.RegionFetcher
|
||||
import deckers.thibault.aves.channel.calls.fetchers.ThumbnailFetcher
|
||||
import deckers.thibault.aves.channel.calls.fetchers.TiffRegionFetcher
|
||||
import deckers.thibault.aves.model.ExifOrientationOp
|
||||
import deckers.thibault.aves.model.provider.FieldMap
|
||||
import deckers.thibault.aves.model.provider.ImageProvider.ImageOpCallback
|
||||
|
@ -102,19 +105,20 @@ class ImageFileHandler(private val activity: Activity) : MethodCallHandler {
|
|||
val regionRect = Rect(x, y, x + width, y + height)
|
||||
when (mimeType) {
|
||||
MimeTypes.TIFF -> TiffRegionFetcher(activity).fetch(
|
||||
uri,
|
||||
sampleSize,
|
||||
regionRect,
|
||||
uri = uri,
|
||||
page = pageId ?: 0,
|
||||
result,
|
||||
sampleSize = sampleSize,
|
||||
regionRect = regionRect,
|
||||
result = result,
|
||||
)
|
||||
else -> regionFetcher.fetch(
|
||||
uri,
|
||||
mimeType,
|
||||
sampleSize,
|
||||
regionRect,
|
||||
Size(imageWidth, imageHeight),
|
||||
result,
|
||||
uri = uri,
|
||||
mimeType = mimeType,
|
||||
pageId = pageId,
|
||||
sampleSize = sampleSize,
|
||||
regionRect = regionRect,
|
||||
imageSize = Size(imageWidth, imageHeight),
|
||||
result = result,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
package deckers.thibault.aves.channel.calls
|
||||
package deckers.thibault.aves.channel.calls.fetchers
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.BitmapRegionDecoder
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.util.Size
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DecodeFormat
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import deckers.thibault.aves.decoder.MultiTrackImage
|
||||
import deckers.thibault.aves.utils.BitmapUtils.getBytes
|
||||
import deckers.thibault.aves.utils.MimeTypes
|
||||
import deckers.thibault.aves.utils.StorageUtils
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import java.io.File
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class RegionFetcher internal constructor(
|
||||
|
@ -17,21 +24,42 @@ class RegionFetcher internal constructor(
|
|||
) {
|
||||
private var lastDecoderRef: LastDecoderRef? = null
|
||||
|
||||
private val pageTempUris = HashMap<Pair<Uri, Int>, Uri>()
|
||||
|
||||
private val multiTrackGlideOptions = RequestOptions()
|
||||
.format(DecodeFormat.PREFER_ARGB_8888)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
|
||||
fun fetch(
|
||||
uri: Uri,
|
||||
mimeType: String,
|
||||
pageId: Int?,
|
||||
sampleSize: Int,
|
||||
regionRect: Rect,
|
||||
imageSize: Size,
|
||||
result: MethodChannel.Result,
|
||||
) {
|
||||
if (MimeTypes.isHeifLike(mimeType) && pageId != null) {
|
||||
val id = Pair(uri, pageId)
|
||||
fetch(
|
||||
uri = pageTempUris.getOrPut(id) { createJpegForPage(uri, pageId) },
|
||||
mimeType = MimeTypes.JPEG,
|
||||
pageId = null,
|
||||
sampleSize = sampleSize,
|
||||
regionRect = regionRect,
|
||||
imageSize = imageSize,
|
||||
result = result,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
val options = BitmapFactory.Options().apply {
|
||||
inSampleSize = sampleSize
|
||||
}
|
||||
|
||||
var currentDecoderRef = lastDecoderRef
|
||||
if (currentDecoderRef != null && currentDecoderRef.uri != uri) {
|
||||
currentDecoderRef.decoder.recycle()
|
||||
currentDecoderRef = null
|
||||
}
|
||||
|
||||
|
@ -74,6 +102,31 @@ class RegionFetcher internal constructor(
|
|||
result.error("getRegion-read-exception", "failed to initialize region decoder for uri=$uri regionRect=$regionRect", e.message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createJpegForPage(sourceUri: Uri, pageId: Int): Uri {
|
||||
val target = Glide.with(context)
|
||||
.asBitmap()
|
||||
.apply(multiTrackGlideOptions)
|
||||
.load(MultiTrackImage(context, sourceUri, pageId))
|
||||
.submit()
|
||||
try {
|
||||
val bitmap = target.get()
|
||||
// if (MimeTypes.needRotationAfterGlide(sourceMimeType)) {
|
||||
// bitmap = BitmapUtils.applyExifOrientation(context, bitmap, sourceEntry.rotationDegrees, sourceEntry.isFlipped)
|
||||
// }
|
||||
bitmap ?: throw Exception("failed to get image from uri=$sourceUri page=$pageId")
|
||||
|
||||
val tempFile = File.createTempFile("aves", null, context.cacheDir).apply {
|
||||
deleteOnExit()
|
||||
outputStream().use { outputStream ->
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
|
||||
}
|
||||
}
|
||||
return Uri.fromFile(tempFile)
|
||||
} finally {
|
||||
Glide.with(context).clear(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class LastDecoderRef(
|
|
@ -1,4 +1,4 @@
|
|||
package deckers.thibault.aves.channel.calls
|
||||
package deckers.thibault.aves.channel.calls.fetchers
|
||||
|
||||
import android.content.ContentUris
|
||||
import android.content.Context
|
|
@ -1,4 +1,4 @@
|
|||
package deckers.thibault.aves.channel.calls
|
||||
package deckers.thibault.aves.channel.calls.fetchers
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
|
@ -13,9 +13,9 @@ class TiffRegionFetcher internal constructor(
|
|||
) {
|
||||
fun fetch(
|
||||
uri: Uri,
|
||||
page: Int,
|
||||
sampleSize: Int,
|
||||
regionRect: Rect,
|
||||
page: Int = 0,
|
||||
result: MethodChannel.Result,
|
||||
) {
|
||||
try {
|
|
@ -227,8 +227,7 @@ class AvesEntry {
|
|||
MimeTypes.rw2,
|
||||
MimeTypes.srw,
|
||||
].contains(mimeType) &&
|
||||
!isAnimated &&
|
||||
pageId == null;
|
||||
!isAnimated;
|
||||
|
||||
bool get supportTiling => _supportedByBitmapRegionDecoder || mimeType == MimeTypes.tiff;
|
||||
|
||||
|
|
Loading…
Reference in a new issue