panpf / zoomimage

ZoomImage is an gesture zoom viewing of images library specially designed for Compose Multiplatform and Android View. Supported scale, pan, locate, rotation, and super-large image subsampling.
Apache License 2.0
336 stars 19 forks source link

CoilAsyncZoomImage子采样失败,The thumbnail aspect ratio is different with the original image #22

Closed XDao7 closed 4 months ago

XDao7 commented 8 months ago

Describe the bug

在使用子采样加载大图的时候,出现了缩略图加载成功,但是子采样失败的问题,log如下:

ZoomableState@9df97bfd. reset:contentScaleChanged. containerSize=522x457, contentSize=522x457, contentOriginSize=0x0, contentScale=Fit, alignment=Center, rotation=0, scalesCalculator=DynamicScalesCalculator(multiple=3.0), readMode=ReadMode(sizeType=3, decider=LongImageDecider(2.5:5.0)). lastContentVisibleCenter=261x228. minScale=1.0, mediumScale=3.0, maxScale=9.0, baseTransform=(1.0x1.0,0.0x0.0,0.0,0.0x0.0,0.5x0.5), userTransform=(1.0x1.0,0.0x0.0,0.0,0.0x0.0,0.0x0.0), transform=(1.0x1.0,0.0x0.0,0.0,0.0x0.0,0.5x0.5)
ZoomableState@9df97bfd. reset:alignmentChanged. All parameters unchanged
ZoomableState@9df97bfd. reset:readModeChanged. All parameters unchanged
ZoomableState@9df97bfd. reset:scalesCalculatorChanged. All parameters unchanged
ZoomableState@9df97bfd. reset:limitOffsetWithinBaseVisibleRectChanged. All parameters unchanged
SubsamplingState@9df97bfd. resetTileDecoder:contentSizeChanged. failed. imageSource=null, contentSize=522x457, 'null'
ZoomableState@9df97bfd. CoilZoomAsyncImage. onState. state=Success. data='http://10.52.12.232:30001/minio-server/zhihuiketang001dev/var/2024/0314/6b8b76ef-b741-47ea-983a-a86fe21c2b50.jpg'
SubsamplingState@9df97bfd. setImageSource. 'null' -> 'http://10.52.12.232:30001/minio-server/zhihuiketang001dev/var/2024/0314/6b8b76ef-b741-47ea-983a-a86fe21c2b50.jpg'
ZoomableState@9df97bfd. reset:contentSizeChanged. containerSize=522x457, contentSize=22x456, contentOriginSize=0x0, contentScale=Fit, alignment=Center, rotation=0, scalesCalculator=DynamicScalesCalculator(multiple=3.0), readMode=ReadMode(sizeType=3, decider=LongImageDecider(2.5:5.0)). lastContentVisibleCenter=261x228. minScale=1.0022, mediumScale=23.7273, maxScale=71.1818, baseTransform=(1.0x1.0,250.0x0.0,0.0,0.0x0.0,0.02x0.5), userTransform=(23.68x23.68,-5918.84x0.0,0.0,0.0x0.0,0.02x0.5), transform=(23.73x23.73,0.0x0.0,0.0,0.0x0.0,0.02x0.5)
SubsamplingState@9df97bfd. resetTileDecoder:contentSizeChanged. error, The thumbnail aspect ratio is different with the original image. contentSize: 22x456, ignoreExifOrientation=false. imageInfo: (1586x31416,'image/jpeg'). 'http://10.52.12.232:30001/minio-server/zhihuiketang001dev/var/2024/0314/6b8b76ef-b741-47ea-983a-a86fe21c2b50.jpg'
SubsamplingState@9df97bfd. resetTileManager:preferredTileSizeChanged. failed. imageSource=CoilImageSource('http://10.52.12.232:30001/minio-server/zhihuiketang001dev/var/2024/0314/6b8b76ef-b741-47ea-983a-a86fe21c2b50.jpg'), contentSize=22x456, preferredTileSize=261x228, tileDecoder=null, 'http://10.52.12.232:30001/minio-server/zhihuiketang001dev/var/2024/0314/6b8b76ef-b741-47ea-983a-a86fe21c2b50.jpg'

想问一下这种情况是图片参数有问题还是什么?可以提供一些帮助么?出问题的原图附在最后了。

Affected platforms

Affected components

Versions

Running Devices

Sample code

val zoomState: ZoomState = rememberZoomState()
LaunchedEffect(Unit) {
    zoomState.zoomable.readMode = ReadMode.Default
}
CoilZoomAsyncImage(
    model = Uri.parse(afterWorkItem.question.getPrefixPath()),
    contentDescription = null,
    modifier = Modifier
        .padding(7.dp)
        .fillMaxSize(),
    state = zoomState
)

Screenshots

Screenshot_20240314_195550

Additional context

6b8b76ef-b741-47ea-983a-a86fe21c2b50

panpf commented 6 months ago

实在抱歉,最近一直在忙别的项目

SubsamplingState@9df97bfd. resetTileDecoder:contentSizeChanged. error, The thumbnail aspect ratio is different with the original image. contentSize: 22x456, ignoreExifOrientation=false. imageInfo: (1586x31416,'image/jpeg'). 'http://10.52.12.232:30001/minio-server/zhihuiketang001dev/var/2024/0314/6b8b76ef-b741-47ea-983a-a86fe21c2b50.jpg'

这一条日志已经给出答案了,原因是原图和缩略图的宽高比的差值超过了 0.5,这是为了确保子采样图盖在缩略图上不会出现明显的错位而做的限制

你可以看一下为什么加载的缩略图相比原图会相差这么大,或者换用别的图片加载库,如果实在无法解决并给出合理性解释,我再考虑适当放开此限制

XDao7 commented 5 months ago

我用同一张图片测试了一下CoilZoomAsyncImage,GlideZoomAsyncImage和SketchZoomAsyncImage,发现只有SketchZoomAsyncImage可以正常进行子采样。

panpf commented 5 months ago

因为 SketchZoomAsyncImage 默认只会等比例的修改图片的尺寸

XDao7 commented 5 months ago

╮(╯-╰)╭已经切换成了SketchZoomAsyncImage,不过有考虑过CoilZoomAsyncImage或者GlideZoomAsyncImage做适配么?不是很清楚他们加载缩略图的规则是啥。

panpf commented 5 months ago

是它们默认解码的图片不符合 zoomimage 的要求,你要调整它们的参数让它们不要修改

XDao7 commented 5 months ago

我在coil当中没有找到哪个设置可以让这张图片的分辨率满足子采样要求

panpf commented 5 months ago

precision(INEXACT)

XDao7 commented 5 months ago

EXACT,INEXACT和AUTOMATIC都不行,我还试过了Scale.FILL,这个似乎是按最短的边设置大小,图片大了还是会OOM。

panpf commented 4 months ago

1.0.0-alpha02 版本会放宽此限制

XDao7 commented 4 months ago

我尝试引入了io.github.panpf.zoomimage:zoomimage-compose-coil2:1.1.0-alpha02,将上述代码中的rememberZoomState()修改为rememberCoilZoomState(),然后有个报错:

sys default last handle start!
FATAL EXCEPTION: main
Process: com.txedu.zhkt, PID: 20720
java.lang.IllegalStateException: closed
    at okio.RealBufferedSource.read(RealBufferedSource.kt:189)
    at okio.RealBufferedSource$inputStream$1.read(RealBufferedSource.kt:162)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:248)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:288)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:347)
    at java.io.FilterInputStream.read(FilterInputStream.java:107)
    at androidx.exifinterface.media.ExifInterface.getMimeType(ExifInterface.java:5341)
    at androidx.exifinterface.media.ExifInterface.loadAttributes(ExifInterface.java:4587)
    at androidx.exifinterface.media.ExifInterface.<init>(ExifInterface.java:4058)
    at androidx.exifinterface.media.ExifInterface.<init>(ExifInterface.java:4013)
    at com.github.panpf.zoomimage.subsampling.internal.Decodes_androidKt.decodeExifOrientation(decodes.android.kt:43)
    at com.github.panpf.zoomimage.subsampling.internal.BitmapRegionDecoderDecodeHelper$Factory.create(BitmapRegionDecoderDecodeHelper.kt:91)
    at com.github.panpf.zoomimage.subsampling.internal.Decodes_androidKt.createDecodeHelper(decodes.android.kt:31)
    at com.github.panpf.zoomimage.subsampling.internal.SubsamplingsKt.decodeAndCreateTileDecoder-ZYX0fMU(subsamplings.kt:43)
    at com.github.panpf.zoomimage.compose.subsampling.SubsamplingState$resetTileDecoder$2$result$1.invokeSuspend(SubsamplingState.kt:402)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:111)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:99)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:811)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:715)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:702)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@1cf81d2, Dispatchers.Main]

新版本在用法上有什么别的改动么?

我还尝试引入了io.github.panpf.zoomimage:zoomimage-compose-coil:1.1.0-alpha02,虽然没有报错,但是没有加载出图片来,包括缩略图都没有,还不清楚是什么原因。

panpf commented 4 months ago

这是 alpha02 为了修复别的问题导致的 bug,正在修复,争取今天发 alpha03

panpf commented 4 months ago

1.1.0-alpha03 版本修复此问题,已发布