fix(photo-editor): 修复照片旋转二次叠加与黑边问题
This commit is contained in:
parent
0a6b9449a3
commit
b7607eebd9
@ -79,6 +79,8 @@ import androidx.compose.ui.graphics.graphicsLayer
|
|||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
|
import androidx.compose.ui.layout.layout
|
||||||
|
import androidx.compose.ui.unit.Constraints
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.semantics.testTagsAsResourceId
|
import androidx.compose.ui.semantics.testTagsAsResourceId
|
||||||
@ -384,14 +386,23 @@ private fun EditableImage(
|
|||||||
val angle = displayRotation.value
|
val angle = displayRotation.value
|
||||||
val offset = angle - state.rotationDegrees
|
val offset = angle - state.rotationDegrees
|
||||||
val scale = RotationGeometry.coverScale(offset, containerAspect)
|
val scale = RotationGeometry.coverScale(offset, containerAspect)
|
||||||
val rotatedBmp = remember(state.rotationDegrees, state.sourceBitmap) {
|
|
||||||
state.rotatedBitmap
|
|
||||||
}
|
|
||||||
Image(
|
Image(
|
||||||
bitmap = rotatedBmp.asImageBitmap(),
|
bitmap = state.sourceBitmap.asImageBitmap(),
|
||||||
contentDescription = "编辑中的照片",
|
contentDescription = "编辑中的照片",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.layout { measurable, constraints ->
|
||||||
|
val isSwapped = (state.rotationDegrees % 180 != 0)
|
||||||
|
val targetWidth = if (isSwapped) constraints.maxHeight else constraints.maxWidth
|
||||||
|
val targetHeight = if (isSwapped) constraints.maxWidth else constraints.maxHeight
|
||||||
|
val placeable = measurable.measure(
|
||||||
|
Constraints.fixed(targetWidth, targetHeight)
|
||||||
|
)
|
||||||
|
layout(constraints.maxWidth, constraints.maxHeight) {
|
||||||
|
val x = (constraints.maxWidth - targetWidth) / 2
|
||||||
|
val y = (constraints.maxHeight - targetHeight) / 2
|
||||||
|
placeable.placeRelative(x, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
rotationZ = angle
|
rotationZ = angle
|
||||||
scaleX = scale
|
scaleX = scale
|
||||||
@ -410,7 +421,7 @@ private fun EditableImage(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
contentScale = ContentScale.Crop
|
contentScale = ContentScale.Fit
|
||||||
)
|
)
|
||||||
|
|
||||||
if (mode == EditTab.CROP && state.cropEnabled) {
|
if (mode == EditTab.CROP && state.cropEnabled) {
|
||||||
@ -644,7 +655,7 @@ private fun ToolPanel(
|
|||||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant)
|
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "${state.rotationDegrees}°",
|
text = "${(state.rotationDegrees % 360 + 360) % 360}°",
|
||||||
style = MaterialTheme.typography.labelMedium,
|
style = MaterialTheme.typography.labelMedium,
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
|||||||
@ -31,6 +31,13 @@ class RotationGeometryTest {
|
|||||||
assertEquals(0.75f, RotationGeometry.stableAspect(1.3333f, 270), 1e-3f)
|
assertEquals(0.75f, RotationGeometry.stableAspect(1.3333f, 270), 1e-3f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun stableAspect_negativeAndMultipleRotations_invertsCorrectly() {
|
||||||
|
// -450° (即 270°) 应与 90° 一致,反转宽高比
|
||||||
|
assertEquals(0.75f, RotationGeometry.stableAspect(1.3333f, -450), 1e-3f)
|
||||||
|
assertEquals(1.3333f, RotationGeometry.stableAspect(1.3333f, -360), 1e-3f)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun coverScale_atStableOffset_isOne() {
|
fun coverScale_atStableOffset_isOne() {
|
||||||
// 稳态(offset=0)零裁剪零黑边
|
// 稳态(offset=0)零裁剪零黑边
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user