Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/diffusers/image_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,11 @@ def _resize_and_fill(
ratio = width / height
src_ratio = image.width / image.height

src_w = width if ratio < src_ratio else image.width * height // image.height
src_h = height if ratio >= src_ratio else image.height * width // image.width
# Floor division collapses the scaled side to 0 for extreme aspect ratios (a 1x2000 image
# scaled to fit 512x512 gives `1 * 512 // 2000 == 0`), and `Image.resize` then fails with
# "height and width must be > 0", which names neither the input nor the side that vanished.
src_w = width if ratio < src_ratio else max(1, image.width * height // image.height)
src_h = height if ratio >= src_ratio else max(1, image.height * width // image.width)

resized = image.resize((src_w, src_h), resample=PIL_INTERPOLATION[self.config.resample])
res = Image.new("RGB", (width, height))
Expand Down Expand Up @@ -451,8 +454,8 @@ def _resize_and_crop(
ratio = width / height
src_ratio = image.width / image.height

src_w = width if ratio > src_ratio else image.width * height // image.height
src_h = height if ratio <= src_ratio else image.height * width // image.width
src_w = width if ratio > src_ratio else max(1, image.width * height // image.height)
src_h = height if ratio <= src_ratio else max(1, image.height * width // image.width)

resized = image.resize((src_w, src_h), resample=PIL_INTERPOLATION[self.config.resample])
res = Image.new("RGB", (width, height))
Expand Down
25 changes: 25 additions & 0 deletions tests/others/test_image_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,28 @@ def test_vae_image_processor_resize_np(self):
assert out_np.shape == exp_np_shape, (
f"resized image output shape '{out_np.shape}' didn't match expected shape '{exp_np_shape}'."
)

def test_resize_fill_and_crop_handle_extreme_aspect_ratios(self):
"""A side must never be scaled down to zero pixels.

`src_w`/`src_h` are computed with floor division, so scaling a very thin image to fit a
square target collapses the short side: `1 * 512 // 2000 == 0`. `PIL.Image.resize` then
raises `ValueError: height and width must be > 0`, which names neither the input nor the
side that vanished.
"""
image_processor = VaeImageProcessor(vae_scale_factor=1)

for size in [(1, 2000), (2000, 1), (1, 1)]:
image = PIL.Image.new("RGB", size)
for resize_mode in ("fill", "crop"):
out = image_processor.resize(image, height=512, width=512, resize_mode=resize_mode)
assert out.size == (512, 512), f"{size} with resize_mode={resize_mode} gave {out.size}"

def test_resize_fill_and_crop_unchanged_for_ordinary_images(self):
"""The clamp must not perturb sizes that were already computed correctly."""
image_processor = VaeImageProcessor(vae_scale_factor=1)

for size in [(64, 64), (900, 3), (3, 900), (1024, 768)]:
image = PIL.Image.new("RGB", size)
for resize_mode in ("fill", "crop"):
assert image_processor.resize(image, height=512, width=512, resize_mode=resize_mode).size == (512, 512)
Loading