diff --git a/app/service/design_fast/utils/synthesis_item.py b/app/service/design_fast/utils/synthesis_item.py index 8b7e55e..b380a81 100644 --- a/app/service/design_fast/utils/synthesis_item.py +++ b/app/service/design_fast/utils/synthesis_item.py @@ -342,33 +342,83 @@ def update_base_size_priority(layers): def transpose_rotate(layer, image): - # transpose[0]是左右 transpose[1]是上下 - transpose = layer.get('transpose', [1, 1]) # 默认为1, 1代表不镜像 + """ + 融合镜像(transpose)和旋转(rotate)逻辑,计算实际旋转角度后执行图像变换, + 并调整粘贴位置以保持视觉中心一致 - rotate = layer.get('rotate', 0) + 参数: + layer: 包含transpose、rotate、adaptive_position等属性的字典 + image: PIL Image对象,待处理的图像 + + 返回: + tuple: (处理后的Image对象, 新的粘贴坐标(x, y)) + """ + # 获取镜像状态(transpose[0]=左右,transpose[1]=上下;1=正常,-1=镜像) + transpose = layer.get('transpose', [1, 1]) + is_mirrored_x = transpose[0] # 左右镜像状态 + is_mirrored_y = transpose[1] # 上下镜像状态 + + # 获取原始旋转角度和粘贴位置 + original_rotate = layer.get('rotate', 0) paste_x, paste_y = layer['adaptive_position'][1], layer['adaptive_position'][0] original_w = image.width original_h = image.height - # transpose左右是1 上下是-1 - if transpose[0] != 1: - # 左右 - image = image.transpose(0) - if transpose[1] != 1: - # 上下 - image = image.transpose(1) + # ------------------- 核心修改:计算实际旋转角度 ------------------- + # 结合镜像状态,计算需要实际执行的旋转角度 + actual_rotate = calculate_actual_rotate(original_rotate, is_mirrored_x, is_mirrored_y) + print(f"actual_rotate:{actual_rotate}") + # ------------------- 执行镜像变换 ------------------- + # 左右镜像(transpose[0] != 1 即-1,表示镜像) + if is_mirrored_x != 1: + image = image.transpose(0) # 假设transpose(0)对应左右翻转(需匹配你的PIL版本) - if rotate: - image = image.rotate(-rotate, expand=True) - # 4. 计算粘贴位置以保持视觉中心一致 - # 原本 (15, 36) 是 288*288 的左上角,我们计算其中心点 + # 上下镜像(transpose[1] != 1 即-1,表示镜像) + if is_mirrored_y != 1: + image = image.transpose(1) # 假设transpose(1)对应上下翻转 + + # ------------------- 执行旋转并调整粘贴位置 ------------------- + if actual_rotate != 0: # 只有实际旋转角度非0时才执行旋转 + # 注意:原代码中是rotate(-rotate),这里同步调整符号 + image = image.rotate(-actual_rotate, expand=True) + + # 计算粘贴位置以保持视觉中心一致 + # 原位置的中心点 target_center_x = paste_x + original_w // 2 target_center_y = paste_y + original_h // 2 - # 获取旋转后图像的新尺寸 + # 旋转后图像的新尺寸 new_w, new_h = image.size - # 计算新的左上角坐标,使得旋转后的图像中心依然在原定的中心位置 + # 新的左上角坐标(保证中心不变) paste_x = target_center_x - new_w // 2 paste_y = target_center_y - new_h // 2 + return image, (paste_x, paste_y) + + +def calculate_actual_rotate(before_rotate, is_mirrored_x, is_mirrored_y): + """ + 根据X/Y轴镜像状态计算实际的旋转角度,并标准化到0-360度 + + 参数: + before_rotate: 原始旋转角度(数值类型) + is_mirrored_x: X轴镜像状态,-1表示镜像,1表示正常 + is_mirrored_y: Y轴镜像状态,-1表示镜像,1表示正常 + + 返回: + float/int: 标准化后的实际旋转角度(0-360度) + """ + actual_rotate = before_rotate + + # 根据镜像状态调整旋转角度 + if is_mirrored_x == -1 and is_mirrored_y == 1: + actual_rotate = -before_rotate + elif is_mirrored_x == 1 and is_mirrored_y == -1: + actual_rotate = -before_rotate + # elif is_mirrored_x == -1 and is_mirrored_y == -1: + # actual_rotate = before_rotate + 180 + + # 角度标准化到0-360度 + normalized_rotate = ((actual_rotate % 360) + 360) % 360 + return normalized_rotate