GithubHelp home page GithubHelp logo

panpf / zoomimage Goto Github PK

View Code? Open in Web Editor NEW
253.0 6.0 12.0 70.41 MB

ZoomImage is a library designed for Compose Multiplatform and Android View for gesture zoom viewing of images, supported scale, pan, locate, rotation, and super-large image subsampling.

License: Apache License 2.0

Kotlin 99.98% Shell 0.02%
android compose huge image locate pan positioning rotation subsampling translation

zoomimage's People

Contributors

panpf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

zoomimage's Issues

请问可以支持一下低版本的kotlin么?

The binary version of its metadata is 1.9.0, expected version is 1.7.1.
在我项目当中编译会提示如上报错,我目前的org.jetbrains.kotlin.android是1.7.20,kotlin版本好像跟compose是绑在一起的,升不上去啊。

怎么单独引用库,现在引用之后完全报错

Describe the problem

Explain the performance issue you're experiencing, including the following details:

  • What specific issue did you encounter? (e.g. missing frames, high CPU usage, memory leaks)
  • Have you noticed any patterns or specific circumstances under which the problem occurs?

Affected platforms

Select of the platforms below:

  • Android
  • Desktop

Affected components

Select of the components below:

  • ZoomImage
  • SketchAsyncZoomImage
  • CoilAsyncZoomImage
  • GlideAsyncZoomImage
  • ZoomImageView
  • SketchZoomImageView
  • CoilZoomImageView
  • GlideZoomImageView
  • PicassoZoomImageView

Versions

  • zoomimage version*:
  • Kotlin version:
  • Compose version(s)* (Jetpack/Multiplatform):
  • JDK version(Only Desktop):

Running Devices

Please accurately describe the device Model, OS version, and CPU Architecture

  • MacBookPro 14 2021; macOS 13.4.1; arm64
  • XiaoMi MIX 4; MIUI 14.0.6; arm64

Sample code

If possible, provide a small piece of code that reproduces the problem. If the code snippet is too
large to paste here, please link to a Gist, a GitHub repo, or any other public code repository.

Reproduction steps

Please provide a detailed step-by-step guide on how to reproduce the issue you are experiencing.

Video

If you're reporting slow app work or missing frames, please provide a video of the problem.

Profiling data

Please provide any relevant profiling data that might be helpful. This could include information
like FPS, memory usage, CPU time, or any other data that could provide insight into the performance
issue.

Additional information

Provide any other details that you think might be helpful for us to understand the problem. This
could include things like the system configuration, external factors, etc.

希望添加对于Bitmap的支持(Support Bitmap for XXXZoomImageView)

如果使用bitmap数据载入GlideZoomImageView中,会有以下提示
if use bitmap into GlideZoomImageView,has following tips

GlideZoomImageView. Can't use Subsampling, unsupported model: 'android.graphics.Bitmap@1e22c0'

example:

    private fun showImage(image: Bitmap) {
        binding.detectImageView.visibility = View.VISIBLE
        Glide.with(this@GalleryFragment)
            .load(image)
            .into(binding.detectImageView)
   }

如果使用SketchZoomImageView 则无法直接使用bitmap数据(需要转换)。
If you use SketchZoomImageView, you cannot use bitmap data directly (conversion is required).
所以希望作者添加对于Bitmap的支持,或者给个修改方法,谢谢!
So I hope the author adds support for Bitmap, or give a modification method, thank you!

请问未来会支持 item 图片过渡效果吗?

这个问题可能有点超出这个库的范畴,但是还是问一下(

zoomimage compose 之后会实现下面的效果吗?视频效果来自 https://github.com/Tencent/QMUI_Android/tree/master/photo/src/main/java/com/qmuiteam/photo/compose

zoomimage view 目前可以用 ChangeImageTransfrom 实现,但是 compose 我不清楚要如何实现 🥲 所以想问问大佬之后会不会内置(?)这种效果

FILE.2023-12-09.20.50.33.mp4

Support for zooming based on mouse pointer & scroll wheel for desktop platforms

Currently, zooming only happens when double-clicking on a specific section of the image. It would be great if zooming via mouse pointer + scroll wheel was also supported (like in the Windows Photos app). As far as I know, the only way to do it right now is by calling ZoomState.scale(...), somehow detecting the scroll event & values and pointer position for the focal point. However, I don't yet know the bounds of this method or how to implement it properly by myself.

使用GlideZoomImageView读取不到contentOriginSize,导致大图像显示模糊

Describe the bug

使用GlideZoomImageView读取不到contentOriginSize,导致大图像显示模糊

Affected platforms

  • Android

Affected components

Select of the components below:

  • GlideAsyncZoomImage
  • GlideZoomImageView

Versions

最新demo

Running Devices

Please accurately describe the device Model, OS version, and CPU Architecture

  • redMi K30 Pro

Sample code

If possible, provide a small piece of code that reproduces the problem. If the code snippet is too
large to paste here, please link to a Gist, a GitHub repo, or any other public code repository.

Reproduction steps

Please provide a detailed step-by-step guide on how to reproduce the issue you are experiencing.

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

20240204-113023
20240204-113015

Additional context

Add any other context about the problem here.

双指捏合缩放的小问题

现象描述
1/当图片两指持续缩小时,两指到达一定的距离后,将不再继续缩小
2/当图片两指放大时,开始两指距离很近,图片不放大,后持续加大两指距离,需要到一定的距离后才能触发图片放大

双指捏和缩放的最小触发距离能不能提供 api 进行设置?

Image not loading

Describe the bug
Followed the instruction and yet image is not loading

Affected platforms

  • Android
  • iOS

Affected components

  • SketchAsyncZoomImage
  • CoilAsyncZoomImage

Sample code
SketchZoomAsyncImage(
uri = "http://sample.com/huge_world.jpeg",
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
)

CoilZoomAsyncImage(
model = "http://sample.com/huge_world.jpeg",
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
)

加载部分图片出现闪退

E #++++++++++++++++++++++++++++++++++++++++++#
10:41:51.870 eup E sys default last handle start!
10:41:51.870 AndroidRuntime E FATAL EXCEPTION: main
Process: com.trim.app, PID: 6882
java.util.NoSuchElementException: List is empty.
at kotlin.collections.CollectionsKt___CollectionsKt.last(_Collections.kt:418)
at com.github.panpf.zoomimage.view.subsampling.SubsamplingEngine.resetTileManager(SubsamplingEngine.kt:504)
at com.github.panpf.zoomimage.view.subsampling.SubsamplingEngine.access$resetTileManager(SubsamplingEngine.kt:65)
at com.github.panpf.zoomimage.view.subsampling.SubsamplingEngine$resetTileDecoder$2.invokeSuspend(SubsamplingEngine.kt:439)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@18e955b, Dispatchers.Main]

image
这里entry.value为空list

使用的是GlideZoomImageView

正在想办法把图导出来

如何获取手势缩放的倍数?

在Compose HorizontalPager中使用CoilZoomAsyncImage, 当图片双指放大,滑动图片到边缘后,滑动手势会与Pager的滑动有一些冲突,我想在当用户放大图片后,禁用HorizontalPager的滑动。此时需要获取到图片的手势缩放倍数是否为1。

zoomState.zoomable.transform.scale.scaleX返回的是图像内容的缩放倍数而不是手势缩放倍数,当图片小100100,控件大小为200200时,缩放模式为Fit,此时默认状态下scaleX是2。我需要的是此时默认scaleX大小为1,这个手势缩放的倍数该怎么算

关于缩放限制的问题

compose版本:
1、minscale好像无法自定义数值,比如产品要求在最小在20%,但是我无法限制他

data class MyScalesCalculator(
    val customMinScale: Float,
    val customMediumScale: Float = 3f,
    val customMaxScale: Float
) : ScalesCalculator {

    override fun calculate(
        containerSize: IntSizeCompat,
        contentSize: IntSizeCompat,
        contentOriginSize: IntSizeCompat,
        contentScale: ContentScaleCompat,
        minScale: Float,
        initialScale: Float
    ): ScalesCalculator.Result {
        return ScalesCalculator.Result(
            minScale = customMinScale,
            mediumScale = customMediumScale,
            maxScale = customMaxScale
        )
    }

    override fun toString(): String {
        return "CustomScalesCalculator(" +
                "customMinScale=${customMinScale}, " +
                "customMediumScale=${customMediumScale}, " +
                "customMaxScale=${customMaxScale})"
    }
}

2、关于触摸事件,好像无法捕获到up和cancel事件,能否开放down和up事件。一些需求场景是需要操作的时候隐藏一些ui,然后抬起后过几秒显示一些ui。
我尝试用pointinput无法拦截,使用pointerInteropFilter也只能获取down事件

zoomimage-compose-coil:1.0.0-beta04找不到ZoomState

引入io.github.panpf.zoomimage:zoomimage-compose-coil:1.0.0-beta04后,编译找不到ZoomState类和rememberZoomState()方法。
之前引入io.github.panpf.zoomimage:zoomimage-compose-coil:1.0.0-beta03时是能正常调用ZoomState和rememberZoomState()的。

无法引入依赖库

Describe the bug

无法引入GlideView的依赖库

Affected platforms

Select of the platforms below:

  • Android

Affected components
无法引入其他依赖库, 只能引入stecker的依赖库, 不知道是不是我项目和库的依赖,kotlin版本冲突还是编译器的问题
Select of the components below:

  • ZoomImageView
  • CoilZoomImageView
  • GlideZoomImageView
  • PicassoZoomImageView

Versions

  • zoomimage version*: 1.0.1
  • Kotlin version*: 1.6.21

Running Devices

Please accurately describe the device Model, OS version, and CPU Architecture

  • XiaoMi Red mi note13; MIUI 14.0.6; arm64

Sample code

Reproduction steps

Please provide a detailed step-by-step guide on how to reproduce the issue you are experiencing.

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

直接引入依赖库

Additional context

image

单指缩放问题

单指缩放好像有点问题
无法通过zoomable.disabledGestureTypeState.value = GestureType.ONE_FINGER_SCALE关闭单指缩放,且单指缩放与setOnLongClickListener冲突,会同时触发。还有一个问题是单指缩放会先触发双击缩放,单指缩放的变换位置变成了右下角

Select one of the platforms below:

  • Android

Versions

  • zoomimage version*:1.0.0-beta06
  • Kotlin version*:1.9.0
  • Compose version(s)* (Jetpack/Multiplatform):无
  • Running Devices (*) (Model, OS, CPU Architecture, JDK.):
    • XiaoMi 13 Pro; MIUI 14.0.23.9.18.DEV; arm64
this.imageView.zoomable.disabledGestureTypeState.value = GestureType.ONE_FINGER_SCALE
this.imageView.setOnLongClickListener {
    App.output.showImageLongClickDialog(this.imageInfo!!.path)

    return@setOnLongClickListener true
}
this.imageView.setOnClickListener {
    (this.itemView.context as ImageActivity).onBackPressedDispatcher.onBackPressed()
}

Reproduction steps

无法通过zoomable.disabledGestureTypeState.value = GestureType.ONE_FINGER_SCALE关闭单指缩放,且单指缩放与setOnLongClickListener冲突,会同时触发。还有一个问题是单指缩放会先触发双击缩放,单指缩放的变换位置变成了右下角

File descriptor from content URI isn't closed when disposed

Describe the bug

.close isn't called (or .use isn't used) when the file descriptor (here from a content URI) is not needed anymore when using supersampling.

Affected platforms

Select of the platforms below:

  • Android
  • Desktop

Versions

  • zoomimage version: 1.1.0-alpha01
  • Kotlin version: 2.0.0-RC1
  • Compose version(s)):1.6.8

Running Devices

  • Samsung Galaxy A12; One UI Core 4.1; arm64

Code sample

// Create a ZoomImage with a zoomState and set the subsampling
zoomState.subsampling.setImageSource(Uri.parse("content://..."))

Reproduction step

  • Create an image with subsampling using a content URI
  • Zoom
  • Unzoom

Error/stacktrace

Details

StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:1987) at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:336) at android.os.ParcelFileDescriptor.finalize(ParcelFileDescriptor.java:1069) at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:339) at java.lang.Daemons$FinalizerDaemon.processReference(Daemons.java:324) at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:300) at java.lang.Daemons$Daemon.run(Daemons.java:145) at java.lang.Thread.run(Thread.java:1012) Caused by: java.lang.Throwable: Explicit termination method 'close' not called at dalvik.system.CloseGuard.openWithCallSite(CloseGuard.java:288) at dalvik.system.CloseGuard.open(CloseGuard.java:257) at android.os.ParcelFileDescriptor.(ParcelFileDescriptor.java:206) at android.os.ParcelFileDescriptor$2.createFromParcel(ParcelFileDescriptor.java:1129) at android.os.ParcelFileDescriptor$2.createFromParcel(ParcelFileDescriptor.java:1120) at android.os.storage.IStorageManager$Stub$Proxy.openProxyFileDescriptor(IStorageManager.java:3577) at android.os.storage.StorageManager.openProxyFileDescriptor(StorageManager.java:2141) at android.os.storage.StorageManager.openProxyFileDescriptor(StorageManager.java:2202) at fr.theskyblockman.lifechest.vault.EncryptedContentProvider.openFile(EncryptedContentProvider.kt:159) at android.content.ContentProvider.openAssetFile(ContentProvider.java:2138) at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:2314) at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:2381) at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:562) at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:2034) at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1849) at android.content.ContentResolver.openInputStream(ContentResolver.java:1525) at com.github.panpf.zoomimage.subsampling.ContentImageSource$openSource$2.invokeSuspend(AndroidImageSource.kt:101) at com.github.panpf.zoomimage.subsampling.ContentImageSource$openSource$2.invoke(Unknown Source:8) at com.github.panpf.zoomimage.subsampling.ContentImageSource$openSource$2.invoke(Unknown Source:4) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61) at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:163) at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1) at com.github.panpf.zoomimage.subsampling.ContentImageSource.openSource-IoAF18A(AndroidImageSource.kt:99) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper$getOrCreateDecoder$2.invokeSuspend(BitmapFactoryDecodeHelper.kt:80) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper$getOrCreateDecoder$2.invoke(Unknown Source:8) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper$getOrCreateDecoder$2.invoke(Unknown Source:4) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61) at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:163) at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper.getOrCreateDecoder(BitmapFactoryDecodeHelper.kt:79) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper.access$getOrCreateDecoder(BitmapFactoryDecodeHelper.kt:25) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper$decodeRegion$2.invokeSuspend(BitmapFactoryDecodeHelper.kt:47) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper$decodeRegion$2.invoke(Unknown Source:8) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper$decodeRegion$2.invoke(Unknown Source:4) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61) at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:163) at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1) at com.github.panpf.zoomimage.subsampling.internal.BitmapFactoryDecodeHelper.decodeRegion(BitmapFactoryDecodeHelper.kt:39) at com.github.panpf.zoomimage.subsampling.internal.TileDecoder$decode$tileBitmap$1.invokeSuspend(TileDecoder.kt:57) at com.github.panpf.zoomimage.subsampling.internal.TileDecoder$decode$tileBitmap$1.invoke(Unknown Source:8) at com.github.panpf.zoomimage.subsampling.internal.TileDecoder$decode$tileBitmap$1.invoke(Unknown Source:4) at com.github.panpf.zoomimage.subsampling.internal.TileDecoder$useDecoder$2.invokeSuspend(TileDecoder.kt:75) 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) at com.github.panpf.zoomimage.subsampling.internal.TileDecoder$decode$tileBitmap$1.invoke(Unknown Source:8) at com.github.panpf.zoomimage.subsampling.internal.TileDecoder$decode$tileBitmap$1.invoke(Unknown Source:4) at com.github.panpf.zoomimage.subsampling.internal.TileDecoder$useDecoder$2.invokeSuspend(TileDecoder.kt:75) 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)

Failed to transform zoomimage-view-1.0.0-beta04.aar (io.github.panpf.zoomimage:zoomimage-view:1.0.0-beta04)

先感谢下作者,我在单独引用这个implementation("io.github.panpf.zoomimage:zoomimage-view:1.0.0-beta04")
但是提示我下载不下来,我在阿里云镜像仓里也发现了这个依赖,但是Sync后一运行就会报
`Execution failed for task ':app:mergeDebugAssets'.

Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
Failed to transform zoomimage-view-1.0.0-beta04.aar (io.github.panpf.zoomimage:zoomimage-view:1.0.0-beta04) to match attributes {artifactType=android-assets, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
> Could not find zoomimage-view-1.0.0-beta04.aar (io.github.panpf.zoomimage:zoomimage-view:1.0.0-beta04).
Searched in the following locations:
https://maven.aliyun.com/repository/public/io/github/panpf/zoomimage/zoomimage-view/1.0.0-beta04/zoomimage-view-1.0.0-beta04.aar
https://maven.aliyun.com/repository/public/io/github/panpf/zoomimage/zoomimage-view/1.0.0-beta04/zoomimage-view-1.0.0-beta04.jar`
我换成Glide的依赖也不行,劳烦作者大大帮忙看下,万分感谢!Salute to you!

单指多指切换、fling到边界时的问题

1.单指多指切换问题:
首先单指滑动一段距离,然后再一根指头触摸进行缩放,这时图片会瞬移一段距离,体验非常不好。我看了一下代码,貌似是单指到多指切换时的焦点发生了改变,我下载了源码改动如下,自己大概测试是没问题,由于也没细看源码,所以还请大佬看一下是否有问题。

//CoreZoomUtils.kt

fun calculateTransformOffset(
    currentScale: Float,
    currentOffset: OffsetCompat,
    targetScale: Float,
    centroid: OffsetCompat,
    pan: OffsetCompat,
    gestureRotate: Float,
    pointCountChanged: Boolean    //加了个触摸点数量是否变化的判断。除了下面 TouchHelper.kt 的调用,其他地方都传入的 false
): OffsetCompat {
    //省略..

    //根据触摸数量是否发生了变化来决定是否平移
    val targetRestoreScaleCurrentOffset = if (pointCountChanged) {
        (restoreScaleCurrentOffset + centroid / oldScale).rotateBy(gestureRotate) - (centroid / newScale)
    } else {
        (restoreScaleCurrentOffset + centroid / oldScale).rotateBy(gestureRotate) - (centroid / newScale + pan / oldScale)
    }
    val targetOffset = targetRestoreScaleCurrentOffset * newScale * -1f
    return targetOffset
}
//TouchHelper.kt

    private var lastPointCount = 0   //全局变量

    init {
        gestureDetector = UnifiedGestureDetector(
            onGestureCallback = { scaleFactor: Float, focus: OffsetCompat, panChange: OffsetCompat, pointCount: Int ->
                coroutineScope.launch {

                    val pointCountChanged = lastPointCount != pointCount   //是否触摸点数量发生变化

                    //省略..

                    if (supportOneFingerScale && pointCount == 1 && doubleTapPressPoint != null) {

                        //省略..

                        zoomable.gestureTransform(
                            centroid = doubleTapPressPoint,
                            panChange = OffsetCompat.Zero,
                            zoomChange = scale,
                            rotationChange = 0f,
                            pointCountChanged = pointCountChanged
                        )
                    } else {
                        oneFingerScaleExecuted = false
                        if (supportTwoFingerScale || supportDrag) {

                            //省略..

                            zoomable.gestureTransform(
                                centroid = focus,
                                panChange = finalPan,
                                zoomChange = finalZoom,
                                rotationChange = 0f,
                                pointCountChanged = pointCountChanged
                            )
                        }
                    }

                    lastPointCount = pointCount
                }
            },
        )
    }


2.fling到边界时的问题:
快速fling到边界时会发生图片该边进入到屏幕内部,看起来就是逃脱了边界限制,不过只有大概一帧的时间。

https://github.com/panpf/zoomimage/assets/41738211/8dc55c92-edc1-42c0-ab46-8e37a54e06c0



最后感谢大佬这个库真的好用😄

SketchZoomAsync with Compose Multiplatform 1.7.0-alpha01 does not load any image(s)

Describe the bug
This was printed in my log - SubsamplingState. resetTileDecoder:setImageSource. error, java.util.concurrent.CancellationException: cleanTileDecoder:resetTileDecoder:contentSizeChanged. contentSize: 1026x2051, 'https://image.png'

Affected platforms

Select of the platforms below - Android
[Not tested on other platform]

Affected components

Select of the components below:

  • SketchZoomImageView

Versions

  • zoomimage version*: v1.1.0-alpha02
  • Kotlin version*:
  • Compose version(s)* (Multiplatform): 1.7.0-alpha01
  • JDK version(Only Desktop): N/A

Running Devices

Please accurately describe the device Model, OS version, and CPU Architecture

  • Pixel 7a, Android 14

Sample code

SketchZoomAsyncImage(
    request = request,
    contentDescription = contentDescription,
    modifier = modifier,
    contentScale = ContentScale.Crop,
    state = imageState,
)

Reproduction steps

Just run the above code

Expected behavior

Should display the image

Screenshots

N/A

使用Glide Rotate transform 旋转图片,双支缩放图像显示异常

Describe the bug

修改了Demo 中GlideZoomImageViewFragment loadImage方法
image

然后放大图片,图片旋转角度变化了

Affected platforms

Select of the platforms below:

  • Android

Affected components

  • GlideZoomImageView

Versions
io.github.panpf.zoomimage:zoomimage-view-glide:1.0.2"

  • zoomimage version*:
  • Kotlin version*:
  • Compose version(s)* (Jetpack/Multiplatform):
  • JDK version(Only Desktop):

Running Devices

  • MacBookPro 14 2021; macOS 13.4.1; arm64
  • Google pixel4; arm64

Sample code

If possible, provide a small piece of code that reproduces the problem. If the code snippet is too
large to paste here, please link to a Gist, a GitHub repo, or any other public code repository.

Reproduction steps

Please provide a detailed step-by-step guide on how to reproduce the issue you are experiencing.

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

screen-20240724-153554.1.mp4

Additional context

Add any other context about the problem here.

Subsampling doesn't work for CoilAsyncZoomImage - RuntimeException: Canvas: trying to draw too large(308544000bytes) bitmap.

The image size is 12000 × 6428 px
Image format - webp, jpg

Example test image:
test

java.lang.RuntimeException: Canvas: trying to draw too large(308544000bytes) bitmap.
at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:266)
at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:94)
at androidx.compose.ui.graphics.AndroidCanvas.drawImageRect-HPBpro0(AndroidCanvas.android.kt:275)
at androidx.compose.ui.graphics.drawscope.CanvasDrawScope.drawImage-AZ2fEMs(CanvasDrawScope.kt:256)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawImage-AZ2fEMs(Unknown Source:24)
at androidx.compose.ui.graphics.drawscope.DrawScope.drawImage-AZ2fEMs$default(DrawScope.kt:551)
at androidx.compose.ui.graphics.painter.BitmapPainter.onDraw(BitmapPainter.kt:93)
at androidx.compose.ui.graphics.painter.Painter.draw-x_KDEd0(Painter.kt:212)
at coil3.compose.AsyncImagePainter.onDraw(AsyncImagePainter.kt:211)
at androidx.compose.ui.graphics.painter.Painter.draw-x_KDEd0(Painter.kt:212)
at com.github.panpf.zoomimage.compose.coil.internal.ContentPainterModifier.draw(ContentPainterModifier.kt:205)
at androidx.compose.ui.node.BackwardsCompatNode.draw(BackwardsCompatNode.kt:349)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:364)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:353)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:176)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:66)
at com.github.panpf.zoomimage.compose.subsampling.SubsamplingDrawTilesNode.draw(subsampling.common.kt:104)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:364)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:54)
at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:383)
at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:382)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2303)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:500)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:256)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:382)
at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:380)
at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:209)
at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:335)
at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:1236)
at android.view.View.draw(View.java:23892)
at android.view.View.updateDisplayListIfDirty(View.java:22756)
at android.view.View.draw(View.java:23620)
at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
at android.view.View.updateDisplayListIfDirty(View.java:22747)
at android.view.View.draw(View.java:23620)
at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
at android.view.View.updateDisplayListIfDirty(View.java:22747)
at android.view.View.draw(View.java:23620)
at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317) (Ask Gemini)
at android.view.View.updateDisplayListIfDirty(View.java:22747)
at android.view.View.draw(View.java:23620)
at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
at android.view.View.draw(View.java:23892)
at com.android.internal.policy.DecorView.draw(DecorView.java:809)
at android.view.View.updateDisplayListIfDirty(View.java:22756)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:694)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:700)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:798)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:4939)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4643)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3822)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9305)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1339)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:882)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

Affected platforms

  • Android (Compose Multiplatform)

Affected components

  • CoilAsyncZoomImage

Versions

  • zoomimage version*: 1.1.0-alpha05
  • Kotlin version*: 1.9.23
  • Compose version(s)* (Jetpack/Multiplatform): compose bom 2024.05.00

Running Devices

Please accurately describe the device Model, OS version, and CPU Architecture

  • android emulator OS 14

Sample code

val imageRequest = ImageRequest.Builder(koinInject<PlatformContext>())
        .data("url/path to large image")
        .size(coil3.size.Size.ORIGINAL)
        .build()
    val zoomableState: CoilZoomState = rememberCoilZoomState()
    val imageLoader = koinInject<ImageLoader>()
    CoilZoomAsyncImage(
        modifier = modifier,
        model = imageRequest,
        imageLoader = imageLoader,
        zoomState = zoomableState,
        contentDescription = "",
    )

Glide Compose 版本兼容问题

大佬真的高效,这么快就修复问题了。另外还有个关于 Glide 的问题想反馈下。现在 zoomimage 中使用的 glide-ktx 是 1.0.0-alpha.3 版本,而最新版本(1.0.0-alpha.6)的 glide-compose 关联的是 1.0.0-alpha.5 版本的 glide-ktx ,高版本的 AsyncGlideSize 类不包含构造函数,而由于 zoomimage 中还是会通过有参构造函数来实例化 AsyncGlideSize,所以如果引用方使用的是最新版本的 glide-compose 的话,就会在运行时由于 GlideZoomAsyncImage 而崩溃了

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

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

  • Android

Affected components

  • CoilAsyncZoomImage

Versions

  • zoomimage version*:1.0.2
  • Kotlin version*:1.9.0
  • Compose version(s)* (Jetpack/Multiplatform):compose-bom:2023.08.00, kotlinCompilerExtensionVersion '1.5.1'

Running Devices

  • 华为平板C3 BZH-W30 arm64-v8a

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

希望zoomimage-view-glide的newGlideImageSource可以增加对GlideUrl类型的model的支持

在使用zoomimage-view-glide 1.0.0-beta10加载图片的时候,使用了glide内置GlideUrl类型的model (com.bumptech.glide.load.model.GlideUrl) 以支持指定header

Glide.with(context)
         .load(GlideUrl(url, headers))
         .into(itemImage)

运行时发现一个warning
image
看了下代码,发现newGlideImageSource只支持简单的String Int等类型的model,
image
希望增加对GlideUrl类型的model的支持

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.