fix: correct fx resize behavior

This commit is contained in:
2026-03-14 01:07:24 +08:00
parent f9a312b80a
commit 67502cb932
3 changed files with 56 additions and 15 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@
/data
/pyrightconfig.json
/pyrightconfig.toml
/uv.lock
# 缓存文件
__pycache__

View File

@ -194,23 +194,27 @@ class ImageFilterImplement:
# 缩放
@staticmethod
def apply_resize(image: Image.Image, scale: float = 1.5, scale_y = None) -> Image.Image:
# scale 可以为负
# 如果 scale 为负,则代表翻转
if scale_y is not None:
if float(scale_y) < 0:
scale_x = float(scale)
scale_y_value = float(scale_y) if scale_y is not None else None
if scale_y_value is not None:
if scale_y_value < 0:
image = ImageOps.flip(image)
scale_y = abs(float(scale_y))
if scale < 0:
scale_y_value = abs(scale_y_value)
if scale_x < 0:
image = ImageOps.mirror(image)
scale = abs(scale)
new_size = (int(image.width * scale), int(image.height * float(scale_y)))
return image.resize(new_size, Image.Resampling.LANCZOS)
if scale < 0:
scale_x = abs(scale_x)
target_scale_y = scale_y_value
else:
if scale_x < 0:
image = ImageOps.mirror(image)
image = ImageOps.flip(image)
scale = abs(scale)
new_size = (int(image.width * scale), int(image.height * scale))
return image.resize(new_size, Image.Resampling.LANCZOS)
scale_x = abs(scale_x)
target_scale_y = scale_x
new_width = max(1, round(image.width * scale_x))
new_height = max(1, round(image.height * target_scale_y))
return image.resize((new_width, new_height), Image.Resampling.LANCZOS)
# 波纹
@staticmethod

View File

@ -35,3 +35,39 @@ def test_apply_jpeg_damage_clamps_quality_range():
assert high.size == image.size
assert low.mode == "RGBA"
assert high.mode == "RGBA"
def test_apply_resize_clamps_small_result_to_at_least_one_pixel():
image = Image.new("RGBA", (10, 10), (255, 0, 0, 255))
result = ImageFilterImplement.apply_resize(image, 0.01)
assert result.size == (1, 1)
def test_apply_resize_negative_x_with_positive_y_only_mirrors_horizontally():
image = Image.new("RGBA", (2, 1))
image.putpixel((0, 0), (255, 0, 0, 255))
image.putpixel((1, 0), (0, 0, 255, 255))
result = ImageFilterImplement.apply_resize(image, -1, 1)
assert result.size == (2, 1)
assert result.getpixel((0, 0)) == (0, 0, 255, 255)
assert result.getpixel((1, 0)) == (255, 0, 0, 255)
def test_apply_resize_negative_scale_without_y_flips_both_axes():
image = Image.new("RGBA", (2, 2))
image.putpixel((0, 0), (255, 0, 0, 255))
image.putpixel((1, 0), (0, 255, 0, 255))
image.putpixel((0, 1), (0, 0, 255, 255))
image.putpixel((1, 1), (255, 255, 0, 255))
result = ImageFilterImplement.apply_resize(image, -1)
assert result.size == (2, 2)
assert result.getpixel((0, 0)) == (255, 255, 0, 255)
assert result.getpixel((1, 0)) == (0, 0, 255, 255)
assert result.getpixel((0, 1)) == (0, 255, 0, 255)
assert result.getpixel((1, 1)) == (255, 0, 0, 255)