From 0a2e9a42e7f20fc76b5c4f118030fdafe0256d42 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Tue, 22 Sep 2026 17:35:59 +0200 Subject: [PATCH] fix: detect the real image type of bare base64 generated images (#30359) Generated images that come back as bare base64 (OpenAI b64_json, Gemini bytesBase64Encoded and inlineData, Automatic1111) were always stored as generated-image.png with content type image/png, even when the provider returned JPEG or WebP, for example with {"output_format": "jpeg"} in the OpenAI extra params. The image still rendered because browsers read the bytes, but the download name, the served Content-Type and the type sent along on a later image edit were wrong. Bare base64 carries no format, so the type is now read from the bytes with Pillow, the same way the file already inspects images elsewhere. A response that is not an image at all now fails the generation instead of storing a broken png. The file extension comes from the module's own extension map first, because the Python 3.11 Docker image has no mime database entry for WebP and would otherwise name the file generated-imageNone. Fixes #29948 --- backend/open_webui/routers/images.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/images.py b/backend/open_webui/routers/images.py index 8c6e772896..c894f2c651 100644 --- a/backend/open_webui/routers/images.py +++ b/backend/open_webui/routers/images.py @@ -509,8 +509,9 @@ async def get_image_data(data: str, headers=None, trusted_base_url: str | None = mime_type = header.split(';')[0].lstrip('data:') img_data = base64.b64decode(encoded) else: - mime_type = 'image/png' img_data = base64.b64decode(data) + with Image.open(io.BytesIO(img_data)) as image: + mime_type = Image.MIME.get(image.format, 'image/png') return img_data, mime_type except Exception as e: log.exception(f'Error loading image data: {e}') @@ -520,7 +521,7 @@ async def get_image_data(data: str, headers=None, trusted_base_url: str | None = async def upload_image(request, image_data, content_type, metadata, user, db=None): if image_data is None or content_type is None: raise ValueError('Failed to retrieve image data from the generation backend') - image_format = mimetypes.guess_extension(content_type) + image_format = IMAGE_FILE_EXTENSIONS.get(content_type.lower()) or mimetypes.guess_extension(content_type) or '.png' file = UploadFile( file=io.BytesIO(image_data), filename=f'generated-image{image_format}', # will be converted to a unique ID on upload_file