Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ __pycache__
**/.vscode test/**
**/.vscode-smoke/**
**/.venv*/
venv
bin/**
build/**
obj/**
Expand Down
27 changes: 27 additions & 0 deletions integration_tests/test_save_img.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this code to a keras/src/utils/image_utils_test.py file?

This should be fast enough, it doesn't need to be an integration test.

Then use the standard patterns:

  • create a class that extends testing.TestCase
  • use from absl.testing import parameterized instead of pytest.mark.parametrize
  • use self.get_temp_dir() to get a temp dir

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can now remove this file.


import numpy as np
import pytest

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


@pytest.mark.parametrize(
"shape, name",
[
((50, 50, 3), "rgb.jpg"),
((50, 50, 4), "rgba.jpg"),
],
)
def test_save_jpg(tmp_path, shape, name):
img = np.random.randint(0, 256, size=shape, dtype=np.uint8)
path = tmp_path / name
save_img(path, img, file_format="jpg")
assert os.path.exists(path)

# Check that the image was saved correctly and converted to RGB if needed.
loaded_img = load_img(path)
loaded_array = img_to_array(loaded_img)
assert loaded_array.shape == (50, 50, 3)
21 changes: 18 additions & 3 deletions keras/src/utils/image_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,28 @@ 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)

# Determine the actual save format (normalize jpg → jpeg for internal use)
save_format = file_format
if file_format is not None and file_format.lower() == "jpg":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be breaking

save_format = "jpeg"
elif file_format is None and isinstance(path, (str, pathlib.Path)):
# Infer format from file extension
ext = pathlib.Path(path).suffix[1:].lower()
if ext == "jpg":
save_format = "jpeg"

# Convert array to PIL Image
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 if saving to JPEG
if img.mode == "RGBA" and save_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)

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


@keras_export(["keras.utils.load_img", "keras.preprocessing.image.load_img"])
Expand Down