Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bf4e0ce
Fix save_img(): support 'jpg' format and handle RGBA
utsab345 Sep 20, 2025
b2a5668
Fix save_img: support 'jpg' format (normalize to JPEG) and add tests
utsab345 Sep 20, 2025
d93f3c5
Fix save_img: normalize jpg→jpeg, handle RGBA→RGB, and improve tests
utsab345 Sep 21, 2025
9ab0b4f
Regenerate API directory
utsab345 Sep 21, 2025
b652534
Add save_img to image_utils.py and integration tests for JPG/RGBA han…
utsab345 Sep 25, 2025
4a6a78e
style: fix formatting with format.sh
utsab345 Sep 30, 2025
2b65f89
Simplify save_img: remove _format, normalize jpg→jpeg, add RGBA→RGB h…
utsab345 Oct 4, 2025
2a5bb21
Merge branch 'keras-team:master' into master
utsab345 Oct 4, 2025
524252e
Simplify save_img: remove _format, normalize jpg→jpeg, add RGBA→RGB h…
utsab345 Oct 4, 2025
97d00f5
Simplify save_img: remove _format, normalize jpg→jpeg, add RGBA→RGB h…
utsab345 Oct 4, 2025
2a24eaa
fix: use save_format variable to avoid modifying file_format parameter
utsab345 Oct 6, 2025
6e0340b
Merge branch 'keras-team:master' into master
utsab345 Oct 8, 2025
5c96717
fix: handle .jpg format without renaming file, improve tests
utsab345 Oct 16, 2025
7b84f95
Merge branch 'keras-team:master' into master
utsab345 Oct 17, 2025
95c3e34
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 Oct 18, 2025
323ca8d
Merge branch 'keras-team:master' into master
utsab345 Oct 18, 2025
29afd91
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 Oct 18, 2025
effc784
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 Oct 18, 2025
305e3d9
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 Oct 18, 2025
913ec5e
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 Oct 18, 2025
1fa75a0
Merge branch 'keras-team:master' into master
utsab345 Oct 25, 2025
80f4d4e
Merge branch 'keras-team:master' into master
utsab345 Oct 28, 2025
ce9e776
fix: simplify file format handling and add inferred format test
utsab345 Oct 28, 2025
4f4e22b
fix: simplify file format handling and add inferred format test
utsab345 Oct 28, 2025
655e9f2
fix: simplify file format handling and add inferred format test
utsab345 Oct 28, 2025
f6b8345
fix: simplify file format handling and add inferred format test
utsab345 Oct 28, 2025
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
16 changes: 14 additions & 2 deletions keras/src/utils/image_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,24 @@ def save_img(path, x, data_format=None, file_format=None, scale=True, **kwargs):
**kwargs: Additional keyword arguments passed to `PIL.Image.save()`.
"""
data_format = backend.standardize_data_format(data_format)

# Infer format from path if not explicitly provided
if file_format is None and isinstance(path, (str, pathlib.Path)):
file_format = pathlib.Path(path).suffix[1:].lower()

# Normalize jpg → jpeg for Pillow compatibility
if file_format and file_format.lower() == "jpg":
file_format = "jpeg"

img = array_to_img(x, data_format=data_format, scale=scale)
if img.mode == "RGBA" and (file_format == "jpg" or file_format == "jpeg"):

# Handle RGBA → RGB conversion for JPEG
if img.mode == "RGBA" and file_format == "jpeg":
warnings.warn(
"The JPG format does not support RGBA images, converting to RGB."
"The JPEG format does not support RGBA images, converting to RGB."
)
img = img.convert("RGB")

img.save(path, format=file_format, **kwargs)


Expand Down
36 changes: 36 additions & 0 deletions keras/src/utils/image_utils_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import os

import numpy as np
from absl.testing import parameterized

from keras.src import testing
from keras.src.utils import img_to_array
from keras.src.utils import load_img
from keras.src.utils import save_img


class SaveImgTest(testing.TestCase, parameterized.TestCase):
@parameterized.named_parameters(
("rgb_explicit_format", (50, 50, 3), "rgb.jpg", "jpg", True),
("rgba_explicit_format", (50, 50, 4), "rgba.jpg", "jpg", True),
("rgb_inferred_format", (50, 50, 3), "rgb_inferred.jpg", None, False),
("rgba_inferred_format", (50, 50, 4), "rgba_inferred.jpg", None, False),
)
def test_save_jpg(self, shape, name, file_format, use_explicit_format):
tmp_dir = self.get_temp_dir()
path = os.path.join(tmp_dir, name)

img = np.random.randint(0, 256, size=shape, dtype=np.uint8)

# Test the actual inferred case - don't pass file_format at all
if use_explicit_format:
save_img(path, img, file_format=file_format)
else:
save_img(path, img) # Let it infer from path

self.assertTrue(os.path.exists(path))

# Verify saved image is correctly converted to RGB if needed
loaded_img = load_img(path)
loaded_array = img_to_array(loaded_img)
self.assertEqual(loaded_array.shape, (50, 50, 3))
Loading