fix(diffusers,vllm-omni,tinygrad): save generated images as PNG explicitly (#10729)

The image backends call PIL Image.save(request.dst) without a format, so
Pillow infers the encoder from the file extension. The core passes an
absolute staging path ending in .tmp (e.g. /staging/localai-output-*.tmp),
which Pillow can't map to a format, raising "unknown file extension: .tmp"
and crashing the worker right after a successful GPU inference.

Pass format="PNG" explicitly. LocalAI serves generated images as PNG
regardless of the temporary path, so this is always correct and no longer
depends on the extension of the destination the core happens to allocate.

diffusers is the reported backend (#10727); vllm-omni and tinygrad carry
the identical latent crash for any .tmp staging destination.

Closes #10727


Assisted-by: Claude:claude-opus-4-8 [Claude Code]

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
LocalAI [bot]
2026-07-07 23:24:58 +02:00
committed by GitHub
parent cd65a1f645
commit 7dde5a4225
3 changed files with 15 additions and 5 deletions

View File

@@ -864,8 +864,13 @@ class BackendServicer(backend_pb2_grpc.BackendServicer):
**kwargs
).images[0]
# save the result
image.save(request.dst)
# save the result. Save as PNG explicitly instead of letting Pillow
# infer the encoder from the extension: the core passes an absolute
# staging path ending in .tmp (e.g. /staging/localai-output-*.tmp),
# which Pillow can't map to a format and would raise
# "unknown file extension: .tmp". LocalAI serves generated images as
# PNG regardless of the temp path.
image.save(request.dst, format="PNG")
return backend_pb2.Result(message="Media generated", success=True)