Open ChannelMU opened 2 weeks ago
在相同的缩放系数和transform.offset.x下,像点的位置不同导致偏离量有差别,这是否与由于子采样区域加载有关?我该如何修正?
Canvas(modifier = Modifier.zooming(zoomState.zoomable))
- 首先你绘制点的坐标需要基于内容大小重新计算,内容大小可以通过 zoomState.zoomable.contentSize 属性获取
- 然后 Canvas 应该始终位于左上角位置,并对 Canvas 应用来自 zoomState 的缩放和位移,如下:
Canvas(modifier = Modifier.zooming(zoomState.zoomable))
抱歉,我试着修改了下,还是有同样的问题,以下是修改后的代码
@Composable fun TestPage() { val zoomState = rememberZoomState() zoomState.zoomable.scalesCalculator= CustomScalesCalculator() zoomState.zoomable.limitOffsetWithinBaseVisibleRect=false
//图像大小为6000*4000
//标记点3000,2000
//计算原像点在原图的位置比例
val xin=100f/6000f
val yin=100f/4000f
//计算在当前内容大小下,像点应在的位置
val x=xin*zoomState.zoomable.contentSize.width
val y=yin*zoomState.zoomable.contentSize.height
Box (modifier = Modifier.size(2000.dp)){
SketchZoomAsyncImage(
imageUri = "file:///storage/emulated/0/Android/data/com.example.app_zt/files/Project1/TEST.JPG",
contentDescription = "view image",
modifier = Modifier.fillMaxSize(),
state = zoomState,
)
Canvas(
modifier = Modifier
.fillMaxSize() // 确保Canvas填满整个父容器
.zooming(zoomState.zoomable)
) {
// 绘制蓝色背景
drawRect(
color = Color.Blue.copy(alpha = 0.5f),
size = size // 覆盖整个画布
)
// 绘制点(例如红色圆点)
drawCircle(
color = Color.Red,
center = Offset(x, y),
radius = 2/zoomState.zoomable.transform.scale.scaleX,
)
}
}
}
我在外部Box设置Size200.dp和2000.dp下进行了测试,标记点原始坐标(100,100):
2000dp下:
![Screenshot_20241015-191055](https://github.com/user-attachments/assets/5d3171bc-b912-4d24-94c8-9c654a7264e0)
200dp下:
![Screenshot_20241015-191028](https://github.com/user-attachments/assets/c81f7ef9-aede-40b2-af59-8cdb80e4e62b)
以下是中心点(3000,2000)的测试结果:
2000dp下:
![Screenshot_20241015-191851](https://github.com/user-attachments/assets/1f31f9ad-8e0d-4d41-adca-e87e61def6a7)
200dp下:
![Screenshot_20241015-191823](https://github.com/user-attachments/assets/044be68d-4dd1-45cd-80ae-23f3e5e33a73)
这也不是像素起点的问题,我偏移了0.5像素((100.5,100.5),(3000.5,2000.5))后同样无法精确定位
在我自己的测试中,即使是在相同的Content大小下,标记点位置的不同,它们偏离的方向距离也不同,我不清楚是否还有哪些细节我没注意到,如果可以的话,希望能够提供一个完整的示例。 非常感谢您的帮助(:
你可以看一下 SketchZoomAsyncImage 函数的 210 行是怎么把子采样的碎片覆盖到图片上并保持同样的缩放和位移的
整理思路还是缩略图是放置在左上角的,ZoomState 基于左上角计算缩放和位移,你就基于左上角绘制你的点,然后应用同样的缩放和位移
Box(Modifier.fillMaxSize()) {
val zoomState = rememberSketchZoomState()
SketchZoomAsyncImage(
uri = "/Users/panpf/Downloads/375937945-2b813cbd-b97d-4723-8210-b67f6117cef4.jpg",
contentDescription = "",
sketch = LocalPlatformContext.current.sketch,
modifier = Modifier.fillMaxSize(),
zoomState = zoomState,
)
val scaleFactor by remember {
derivedStateOf {
val contentSize = zoomState.zoomable.contentSize
ScaleFactor(
scaleX = contentSize.width / 6000f,
scaleY = contentSize.height / 4000f
)
}
}
Canvas(modifier = Modifier.fillMaxSize().zooming(zoomState.zoomable)) {
val point1 = Offset(1500f, 1000f)
val scaledPoint1 = Offset(
point1.x * scaleFactor.scaleX,
point1.y * scaleFactor.scaleY
)
drawCircle(
color = Color.Yellow.copy(alpha = 0.75f),
radius = 20f,
center = scaledPoint1
)
val point2 = Offset(3000f, 2000f)
val scaledPoint2 = Offset(
point2.x * scaleFactor.scaleX,
point2.y * scaleFactor.scaleY
)
drawCircle(
color = Color.Yellow.copy(alpha = 0.75f),
radius = 20f,
center = scaledPoint2
)
val point3 = Offset(4500f, 3000f)
val scaledPoint3 = Offset(
point3.x * scaleFactor.scaleX,
point3.y * scaleFactor.scaleY
)
drawCircle(
color = Color.Yellow.copy(alpha = 0.75f),
radius = 20f,
center = scaledPoint3
)
}
}
我花了 5 分钟帮你写了个示例,你仔细看一下吧
抱歉现在才回复,我测试了您的代码,采用compose-sketch:1.1.0-beta01,仅修改了图像文件路径并设置radius=2f,很遗憾在放大后可以很明显看到绘制的位置并不是在正中心: 上图为(3000f,2000f)设置半径为2f 放大后的显示
Describe the bug
Canvas绘制图形时位置出现偏离
Affected platforms
Select of the platforms below:
Affected components
Select of the components below:
Versions
Running Devices
Please accurately describe the device Model, OS version, and CPU Architecture
Sample code
Reproduction steps 在一张6000 x 4000的图像上使用Canvas在(100,100),(3000,2000)处绘制点,放大后发现绘制的图形均有一定的偏离,且当图像的contentSize变小时这种偏离增大 测试图像(6000*4000,格网间隔为100):
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots 设置:Box.size(200.dp)时: 点位(100,100) 点位(3000,2000) 设置:Box.size(2000.dp)时: 点位(100,100) 点位(3000,2000)
Additional context
Add any other context about the problem here.