refactor(image): 重构图片旋转和恢复逻辑

- 将 needRotation 标志重命名为 rotationApplied
- 修改条件旋转阶段的执行逻辑,基于实际旋转角度判断
- 实现通用的图片恢复旋转功能,支持90/180/270度恢复
- 添加恢复旋转角度计算方法 getRestoreAngle
- 更新水印阶段的旋转状态检查逻辑
- 完善单元测试覆盖各种旋转场景
- 优化日志记录和错误处理流程
This commit is contained in:
2025-11-26 16:05:12 +08:00
parent 95419fee66
commit 40d5874560
6 changed files with 170 additions and 19 deletions

View File

@@ -91,7 +91,7 @@ public class PhotoProcessContext {
private File originalFile;
private File processedFile;
private boolean isLandscape = true;
private boolean needRotation = false;
private boolean rotationApplied = false;
/**
* 图像需要旋转的角度(用于后续Stage使用)

View File

@@ -30,7 +30,8 @@ public class ConditionalRotateStage extends AbstractPipelineStage<PhotoProcessCo
@Override
protected boolean shouldExecuteByBusinessLogic(PhotoProcessContext context) {
return context.getImageType() == ImageType.NORMAL_PHOTO && !context.isLandscape();
Integer rotation = context.getImageRotation();
return context.getImageType() == ImageType.NORMAL_PHOTO && (rotation != null && rotation != 0);
}
@Override
@@ -59,7 +60,7 @@ public class ConditionalRotateStage extends AbstractPipelineStage<PhotoProcessCo
}
context.updateProcessedFile(rotatedFile);
context.setNeedRotation(true);
context.setRotationApplied(true);
log.info("图片已旋转{}度", rotation);
return StageResult.success("已旋转" + rotation + "");

View File

@@ -13,7 +13,9 @@ import java.io.File;
/**
* 恢复图片方向Stage
* 如果之前旋转过图,现在旋转270度恢复为竖图
* 如果之前旋转过图,现在反向旋转恢复原方向
* - rotation=90 时恢复需要旋转270度
* - rotation=270 时恢复需要旋转90度
*/
@Slf4j
@StageConfig(
@@ -30,7 +32,7 @@ public class RestoreOrientationStage extends AbstractPipelineStage<PhotoProcessC
@Override
protected boolean shouldExecuteByBusinessLogic(PhotoProcessContext context) {
return context.getImageType() == ImageType.NORMAL_PHOTO && context.isNeedRotation();
return context.getImageType() == ImageType.NORMAL_PHOTO && context.isRotationApplied();
}
@Override
@@ -41,21 +43,29 @@ public class RestoreOrientationStage extends AbstractPipelineStage<PhotoProcessC
return StageResult.failed("当前文件不存在");
}
Integer rotation = context.getImageRotation();
if (rotation == null) {
return StageResult.skipped("无旋转信息");
}
// 计算恢复旋转需要的角度(反向旋转)
int restoreAngle = getRestoreAngle(rotation);
String extension = getFileExtension(currentFile);
File finalFile = context.getTempFileManager()
.createTempFile("final", extension);
log.debug("恢复图方向(旋转270度): {} -> {}", currentFile.getName(), finalFile.getName());
ImageUtils.rotateImage270(currentFile, finalFile);
log.debug("恢复图方向(旋转{}度): {} -> {}", restoreAngle, currentFile.getName(), finalFile.getName());
rotateByAngle(currentFile, finalFile, restoreAngle);
if (!finalFile.exists()) {
return StageResult.failed("旋转后的文件未生成");
}
context.updateProcessedFile(finalFile);
log.info("图方向已恢复(旋转270度)");
log.info("方向已恢复(旋转{}度)", restoreAngle);
return StageResult.success("已恢复竖图方向");
return StageResult.success("已恢复方向");
} catch (Exception e) {
log.error("图片旋转失败", e);
@@ -63,6 +73,37 @@ public class RestoreOrientationStage extends AbstractPipelineStage<PhotoProcessC
}
}
/**
* 计算恢复方向需要的旋转角度
* @param originalRotation 原始旋转角度
* @return 恢复需要的旋转角度
*/
private int getRestoreAngle(int originalRotation) {
// rotation=90 时,恢复需要旋转270度 (360-90=270)
// rotation=270 时,恢复需要旋转90度 (360-270=90)
// rotation=180 时,恢复需要旋转180度 (360-180=180)
return (360 - originalRotation) % 360;
}
/**
* 根据角度旋转图片
*/
private void rotateByAngle(File input, File output, int angle) throws Exception {
switch (angle) {
case 90:
ImageUtils.rotateImage90(input, output);
break;
case 180:
ImageUtils.rotateImage180(input, output);
break;
case 270:
ImageUtils.rotateImage270(input, output);
break;
default:
break;
}
}
private String getFileExtension(File file) {
String name = file.getName();
int lastDot = name.lastIndexOf('.');

View File

@@ -171,7 +171,7 @@ public class WatermarkStage extends AbstractPipelineStage<PhotoProcessContext> {
}
// 根据旋转状态自己处理 offsetLeft
if (context.isNeedRotation()) {
if (context.isRotationApplied()) {
if (context.getImageRotation() == 90) {
info.setOffsetLeft(OFFSET_FOR_PRINTER);
} else if (context.getImageRotation() == 270) {