Skip to content

Commit 8680ca1

Browse files
TMHSDigitalclaude
andcommitted
fix(snippets): save_baked_image writes the requested format
Image.save_render() takes its format from the scene's render.image_settings; image.file_format is ignored. save_baked_image(..., "OPEN_EXR") therefore wrote a PNG with an .exr name, the common case for precision normal maps. The snippet now sets scene.render.image_settings.file_format for the call, passes scene= to save_render, and restores the previous format in a finally. The bake-high-to-low skill's save step says the same and shows the pattern. Proof (local, .scratch/blender-4.5.11-windows-x64 and blender-5.2.1, magic bytes of the written file, float Non-Color 8x8 image): PNG -> PNG, JPEG -> JPEG, OPEN_EXR -> OPEN_EXR on both; image.source stays GENERATED; scene format restored. Old pattern (img.file_format = "OPEN_EXR"; save_render) -> PNG on both. Closes #332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4de3726 commit 8680ca1

2 files changed

Lines changed: 25 additions & 7 deletions

File tree

‎skills/bake-high-to-low/SKILL.md‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,18 @@ Snippet: `snippets/bake_normal_high_to_low.py`.
114114

115115
### 5. Save the datablock
116116

117-
The bake writes the image **in memory**. `Image.save()` on a `GENERATED` image flips `source` to `'FILE'` and drops the buffer — the trap `examples/image-pixels-testcard/` witnesses. Use `save_render()`:
117+
The bake writes the image **in memory**. `Image.save()` on a `GENERATED` image flips `source` to `'FILE'` and drops the buffer — the trap `examples/image-pixels-testcard/` witnesses. Use `save_render()`.
118+
119+
`save_render()` writes in the format of the **scene's** `render.image_settings`, not `img.file_format`: setting `img.file_format = "OPEN_EXR"` and calling `save_render` still writes a PNG on a default scene. Set the scene's format for the call and restore it:
118120

119121
```python
120-
img.file_format = "PNG"
121-
img.save_render(filepath)
122+
settings = scene.render.image_settings
123+
previous = settings.file_format
124+
settings.file_format = "OPEN_EXR" # or "PNG"
125+
try:
126+
img.save_render(filepath, scene=scene)
127+
finally:
128+
settings.file_format = previous
122129
```
123130

124131
Snippet: `snippets/save_baked_image.py`. Folded save is the wrong size: the trap is its own contract.

‎snippets/save_baked_image.py‎

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
# Write a baked image datablock to disk without dropping the buffer.
22
# Image.save() on a GENERATED image flips source to FILE and the pixels
33
# re-source from disk — empty if the file was not the bake. save_render()
4-
# writes the same PNG and leaves source GENERATED.
4+
# writes the buffer and leaves source GENERATED.
5+
#
6+
# save_render() takes its format from the scene's render.image_settings, not
7+
# from image.file_format: setting image.file_format = "OPEN_EXR" alone still
8+
# writes the scene's format (a PNG by default). Set the scene's settings for
9+
# the call and restore them after.
510
#
611
# Reference:
712
# https://docs.blender.org/api/current/bpy.types.Image.html#bpy.types.Image.save_render
@@ -10,7 +15,13 @@
1015
import bpy
1116

1217

13-
def save_baked_image(image, filepath, file_format="PNG"):
14-
image.file_format = file_format
15-
image.save_render(filepath)
18+
def save_baked_image(image, filepath, file_format="PNG", scene=None):
19+
scene = scene or bpy.context.scene
20+
settings = scene.render.image_settings
21+
previous = settings.file_format
22+
settings.file_format = file_format
23+
try:
24+
image.save_render(filepath, scene=scene)
25+
finally:
26+
settings.file_format = previous
1627
return filepath

0 commit comments

Comments
 (0)