-
Notifications
You must be signed in to change notification settings - Fork 19.7k
Fix: Support 'jpg' format in keras.utils.save_img() #21683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
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 b2a5668
Fix save_img: support 'jpg' format (normalize to JPEG) and add tests
utsab345 d93f3c5
Fix save_img: normalize jpg→jpeg, handle RGBA→RGB, and improve tests
utsab345 9ab0b4f
Regenerate API directory
utsab345 b652534
Add save_img to image_utils.py and integration tests for JPG/RGBA han…
utsab345 4a6a78e
style: fix formatting with format.sh
utsab345 2b65f89
Simplify save_img: remove _format, normalize jpg→jpeg, add RGBA→RGB h…
utsab345 2a5bb21
Merge branch 'keras-team:master' into master
utsab345 524252e
Simplify save_img: remove _format, normalize jpg→jpeg, add RGBA→RGB h…
utsab345 97d00f5
Simplify save_img: remove _format, normalize jpg→jpeg, add RGBA→RGB h…
utsab345 2a24eaa
fix: use save_format variable to avoid modifying file_format parameter
utsab345 6e0340b
Merge branch 'keras-team:master' into master
utsab345 5c96717
fix: handle .jpg format without renaming file, improve tests
utsab345 7b84f95
Merge branch 'keras-team:master' into master
utsab345 95c3e34
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 323ca8d
Merge branch 'keras-team:master' into master
utsab345 29afd91
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 effc784
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 305e3d9
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 913ec5e
Move save_img tests to unit tests and convert to Keras TestCase
utsab345 1fa75a0
Merge branch 'keras-team:master' into master
utsab345 80f4d4e
Merge branch 'keras-team:master' into master
utsab345 ce9e776
fix: simplify file format handling and add inferred format test
utsab345 4f4e22b
fix: simplify file format handling and add inferred format test
utsab345 655e9f2
fix: simplify file format handling and add inferred format test
utsab345 f6b8345
fix: simplify file format handling and add inferred format test
utsab345 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ __pycache__ | |
| **/.vscode test/** | ||
| **/.vscode-smoke/** | ||
| **/.venv*/ | ||
| venv | ||
| bin/** | ||
| build/** | ||
| obj/** | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import os | ||
|
|
||
| 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) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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": | ||
|
||
| 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"]) | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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.pyfile?This should be fast enough, it doesn't need to be an integration test.
Then use the standard patterns:
testing.TestCasefrom absl.testing import parameterizedinstead ofpytest.mark.parametrizeself.get_temp_dir()to get a temp dirThere was a problem hiding this comment.
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.