From 6c54ca552a0a32388e68e2623f009cc9cd04c8c4 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 16 Jun 2025 16:52:57 +0400 Subject: [PATCH] feat: global image compression --- backend/open_webui/config.py | 29 +++++++++++- backend/open_webui/main.py | 10 +++++ backend/open_webui/routers/retrieval.py | 20 +++++---- .../admin/Settings/Documents.svelte | 44 +++++++++++++++++++ .../components/channel/MessageInput.svelte | 27 ++++++++++-- src/lib/components/chat/MessageInput.svelte | 27 ++++++++++-- 6 files changed, 142 insertions(+), 15 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 048c05de29..898ac1b594 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2107,6 +2107,27 @@ RAG_FILE_MAX_SIZE = PersistentConfig( ), ) +FILE_IMAGE_COMPRESSION_WIDTH = PersistentConfig( + "FILE_IMAGE_COMPRESSION_WIDTH", + "file.image_compression_width", + ( + int(os.environ.get("FILE_IMAGE_COMPRESSION_WIDTH")) + if os.environ.get("FILE_IMAGE_COMPRESSION_WIDTH") + else None + ), +) + +FILE_IMAGE_COMPRESSION_HEIGHT = PersistentConfig( + "FILE_IMAGE_COMPRESSION_HEIGHT", + "file.image_compression_height", + ( + int(os.environ.get("FILE_IMAGE_COMPRESSION_HEIGHT")) + if os.environ.get("FILE_IMAGE_COMPRESSION_HEIGHT") + else None + ), +) + + RAG_ALLOWED_FILE_EXTENSIONS = PersistentConfig( "RAG_ALLOWED_FILE_EXTENSIONS", "rag.file.allowed_extensions", @@ -2909,7 +2930,13 @@ AUDIO_STT_MODEL = PersistentConfig( AUDIO_STT_SUPPORTED_CONTENT_TYPES = PersistentConfig( "AUDIO_STT_SUPPORTED_CONTENT_TYPES", "audio.stt.supported_content_types", - os.getenv("AUDIO_STT_SUPPORTED_CONTENT_TYPES", "").split(","), + [ + content_type.strip() + for content_type in os.environ.get( + "AUDIO_STT_SUPPORTED_CONTENT_TYPES", "" + ).split(",") + if content_type.strip() + ], ) AUDIO_STT_AZURE_API_KEY = PersistentConfig( diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index edc7431a85..544756a6e8 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -211,6 +211,8 @@ from open_webui.config import ( RAG_ALLOWED_FILE_EXTENSIONS, RAG_FILE_MAX_COUNT, RAG_FILE_MAX_SIZE, + FILE_IMAGE_COMPRESSION_WIDTH, + FILE_IMAGE_COMPRESSION_HEIGHT, RAG_OPENAI_API_BASE_URL, RAG_OPENAI_API_KEY, RAG_AZURE_OPENAI_BASE_URL, @@ -713,9 +715,13 @@ app.state.config.TOP_K = RAG_TOP_K app.state.config.TOP_K_RERANKER = RAG_TOP_K_RERANKER app.state.config.RELEVANCE_THRESHOLD = RAG_RELEVANCE_THRESHOLD app.state.config.HYBRID_BM25_WEIGHT = RAG_HYBRID_BM25_WEIGHT + + app.state.config.ALLOWED_FILE_EXTENSIONS = RAG_ALLOWED_FILE_EXTENSIONS app.state.config.FILE_MAX_SIZE = RAG_FILE_MAX_SIZE app.state.config.FILE_MAX_COUNT = RAG_FILE_MAX_COUNT +app.state.config.FILE_IMAGE_COMPRESSION_WIDTH = FILE_IMAGE_COMPRESSION_WIDTH +app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT = FILE_IMAGE_COMPRESSION_HEIGHT app.state.config.RAG_FULL_CONTEXT = RAG_FULL_CONTEXT @@ -1558,6 +1564,10 @@ async def get_app_config(request: Request): "file": { "max_size": app.state.config.FILE_MAX_SIZE, "max_count": app.state.config.FILE_MAX_COUNT, + "image_compression": { + "width": app.state.config.FILE_IMAGE_COMPRESSION_WIDTH, + "height": app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT, + }, }, "permissions": {**app.state.config.USER_PERMISSIONS}, "google_drive": { diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index f926959945..ee6f99fbb5 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -432,6 +432,8 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)): # File upload settings "FILE_MAX_SIZE": request.app.state.config.FILE_MAX_SIZE, "FILE_MAX_COUNT": request.app.state.config.FILE_MAX_COUNT, + "FILE_IMAGE_COMPRESSION_WIDTH": request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH, + "FILE_IMAGE_COMPRESSION_HEIGHT": request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT, "ALLOWED_FILE_EXTENSIONS": request.app.state.config.ALLOWED_FILE_EXTENSIONS, # Integration settings "ENABLE_GOOGLE_DRIVE_INTEGRATION": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, @@ -599,6 +601,8 @@ class ConfigForm(BaseModel): # File upload settings FILE_MAX_SIZE: Optional[int] = None FILE_MAX_COUNT: Optional[int] = None + FILE_IMAGE_COMPRESSION_WIDTH: Optional[int] = None + FILE_IMAGE_COMPRESSION_HEIGHT: Optional[int] = None ALLOWED_FILE_EXTENSIONS: Optional[List[str]] = None # Integration settings @@ -847,15 +851,13 @@ async def update_rag_config( ) # File upload settings - request.app.state.config.FILE_MAX_SIZE = ( - form_data.FILE_MAX_SIZE - if form_data.FILE_MAX_SIZE is not None - else request.app.state.config.FILE_MAX_SIZE + request.app.state.config.FILE_MAX_SIZE = form_data.FILE_MAX_SIZE + request.app.state.config.FILE_MAX_COUNT = form_data.FILE_MAX_COUNT + request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH = ( + form_data.FILE_IMAGE_COMPRESSION_WIDTH ) - request.app.state.config.FILE_MAX_COUNT = ( - form_data.FILE_MAX_COUNT - if form_data.FILE_MAX_COUNT is not None - else request.app.state.config.FILE_MAX_COUNT + request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT = ( + form_data.FILE_IMAGE_COMPRESSION_HEIGHT ) request.app.state.config.ALLOWED_FILE_EXTENSIONS = ( form_data.ALLOWED_FILE_EXTENSIONS @@ -1025,6 +1027,8 @@ async def update_rag_config( # File upload settings "FILE_MAX_SIZE": request.app.state.config.FILE_MAX_SIZE, "FILE_MAX_COUNT": request.app.state.config.FILE_MAX_COUNT, + "FILE_IMAGE_COMPRESSION_WIDTH": request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH, + "FILE_IMAGE_COMPRESSION_HEIGHT": request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT, "ALLOWED_FILE_EXTENSIONS": request.app.state.config.ALLOWED_FILE_EXTENSIONS, # Integration settings "ENABLE_GOOGLE_DRIVE_INTEGRATION": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, diff --git a/src/lib/components/admin/Settings/Documents.svelte b/src/lib/components/admin/Settings/Documents.svelte index 738cefc335..e05abf686c 100644 --- a/src/lib/components/admin/Settings/Documents.svelte +++ b/src/lib/components/admin/Settings/Documents.svelte @@ -1144,6 +1144,50 @@ + +
+
{$i18n.t('Image Compression Width')}
+
+ + + +
+
+ +
+
+ {$i18n.t('Image Compression Height')} +
+
+ + + +
+
diff --git a/src/lib/components/channel/MessageInput.svelte b/src/lib/components/channel/MessageInput.svelte index 901e8d58f2..448ce847a2 100644 --- a/src/lib/components/channel/MessageInput.svelte +++ b/src/lib/components/channel/MessageInput.svelte @@ -110,9 +110,30 @@ reader.onload = async (event) => { let imageUrl = event.target.result; - if ($settings?.imageCompression ?? false) { - const width = $settings?.imageCompressionSize?.width ?? null; - const height = $settings?.imageCompressionSize?.height ?? null; + if ( + ($settings?.imageCompression ?? false) || + ($config?.file?.image_compression?.width ?? null) || + ($config?.file?.image_compression?.height ?? null) + ) { + let width = null; + let height = null; + + if ($settings?.imageCompression ?? false) { + width = $settings?.imageCompressionSize?.width ?? null; + height = $settings?.imageCompressionSize?.height ?? null; + } + + if ( + ($config?.file?.image_compression?.width ?? null) || + ($config?.file?.image_compression?.height ?? null) + ) { + if (width > ($config?.file?.image_compression?.width ?? null)) { + width = $config?.file?.image_compression?.width ?? null; + } + if (height > ($config?.file?.image_compression?.height ?? null)) { + height = $config?.file?.image_compression?.height ?? null; + } + } if (width || height) { imageUrl = await compressImage(imageUrl, width, height); diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 867db32a6a..f384c5b8f5 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -355,9 +355,30 @@ reader.onload = async (event) => { let imageUrl = event.target.result; - if ($settings?.imageCompression ?? false) { - const width = $settings?.imageCompressionSize?.width ?? null; - const height = $settings?.imageCompressionSize?.height ?? null; + if ( + ($settings?.imageCompression ?? false) || + ($config?.file?.image_compression?.width ?? null) || + ($config?.file?.image_compression?.height ?? null) + ) { + let width = null; + let height = null; + + if ($settings?.imageCompression ?? false) { + width = $settings?.imageCompressionSize?.width ?? null; + height = $settings?.imageCompressionSize?.height ?? null; + } + + if ( + ($config?.file?.image_compression?.width ?? null) || + ($config?.file?.image_compression?.height ?? null) + ) { + if (width > ($config?.file?.image_compression?.width ?? null)) { + width = $config?.file?.image_compression?.width ?? null; + } + if (height > ($config?.file?.image_compression?.height ?? null)) { + height = $config?.file?.image_compression?.height ?? null; + } + } if (width || height) { imageUrl = await compressImage(imageUrl, width, height);