feat: global image compression

This commit is contained in:
Timothy Jaeryang Baek 2025-06-16 16:52:57 +04:00
parent 2949be4f27
commit 6c54ca552a
6 changed files with 142 additions and 15 deletions

View File

@ -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 = PersistentConfig(
"RAG_ALLOWED_FILE_EXTENSIONS", "RAG_ALLOWED_FILE_EXTENSIONS",
"rag.file.allowed_extensions", "rag.file.allowed_extensions",
@ -2909,7 +2930,13 @@ AUDIO_STT_MODEL = PersistentConfig(
AUDIO_STT_SUPPORTED_CONTENT_TYPES = PersistentConfig( AUDIO_STT_SUPPORTED_CONTENT_TYPES = PersistentConfig(
"AUDIO_STT_SUPPORTED_CONTENT_TYPES", "AUDIO_STT_SUPPORTED_CONTENT_TYPES",
"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( AUDIO_STT_AZURE_API_KEY = PersistentConfig(

View File

@ -211,6 +211,8 @@ from open_webui.config import (
RAG_ALLOWED_FILE_EXTENSIONS, RAG_ALLOWED_FILE_EXTENSIONS,
RAG_FILE_MAX_COUNT, RAG_FILE_MAX_COUNT,
RAG_FILE_MAX_SIZE, RAG_FILE_MAX_SIZE,
FILE_IMAGE_COMPRESSION_WIDTH,
FILE_IMAGE_COMPRESSION_HEIGHT,
RAG_OPENAI_API_BASE_URL, RAG_OPENAI_API_BASE_URL,
RAG_OPENAI_API_KEY, RAG_OPENAI_API_KEY,
RAG_AZURE_OPENAI_BASE_URL, 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.TOP_K_RERANKER = RAG_TOP_K_RERANKER
app.state.config.RELEVANCE_THRESHOLD = RAG_RELEVANCE_THRESHOLD app.state.config.RELEVANCE_THRESHOLD = RAG_RELEVANCE_THRESHOLD
app.state.config.HYBRID_BM25_WEIGHT = RAG_HYBRID_BM25_WEIGHT app.state.config.HYBRID_BM25_WEIGHT = RAG_HYBRID_BM25_WEIGHT
app.state.config.ALLOWED_FILE_EXTENSIONS = RAG_ALLOWED_FILE_EXTENSIONS 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_SIZE = RAG_FILE_MAX_SIZE
app.state.config.FILE_MAX_COUNT = RAG_FILE_MAX_COUNT 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 app.state.config.RAG_FULL_CONTEXT = RAG_FULL_CONTEXT
@ -1558,6 +1564,10 @@ async def get_app_config(request: Request):
"file": { "file": {
"max_size": app.state.config.FILE_MAX_SIZE, "max_size": app.state.config.FILE_MAX_SIZE,
"max_count": app.state.config.FILE_MAX_COUNT, "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}, "permissions": {**app.state.config.USER_PERMISSIONS},
"google_drive": { "google_drive": {

View File

@ -432,6 +432,8 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
# File upload settings # File upload settings
"FILE_MAX_SIZE": request.app.state.config.FILE_MAX_SIZE, "FILE_MAX_SIZE": request.app.state.config.FILE_MAX_SIZE,
"FILE_MAX_COUNT": request.app.state.config.FILE_MAX_COUNT, "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, "ALLOWED_FILE_EXTENSIONS": request.app.state.config.ALLOWED_FILE_EXTENSIONS,
# Integration settings # Integration settings
"ENABLE_GOOGLE_DRIVE_INTEGRATION": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, "ENABLE_GOOGLE_DRIVE_INTEGRATION": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
@ -599,6 +601,8 @@ class ConfigForm(BaseModel):
# File upload settings # File upload settings
FILE_MAX_SIZE: Optional[int] = None FILE_MAX_SIZE: Optional[int] = None
FILE_MAX_COUNT: 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 ALLOWED_FILE_EXTENSIONS: Optional[List[str]] = None
# Integration settings # Integration settings
@ -847,15 +851,13 @@ async def update_rag_config(
) )
# File upload settings # File upload settings
request.app.state.config.FILE_MAX_SIZE = ( request.app.state.config.FILE_MAX_SIZE = form_data.FILE_MAX_SIZE
form_data.FILE_MAX_SIZE request.app.state.config.FILE_MAX_COUNT = form_data.FILE_MAX_COUNT
if form_data.FILE_MAX_SIZE is not None request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH = (
else request.app.state.config.FILE_MAX_SIZE form_data.FILE_IMAGE_COMPRESSION_WIDTH
) )
request.app.state.config.FILE_MAX_COUNT = ( request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT = (
form_data.FILE_MAX_COUNT form_data.FILE_IMAGE_COMPRESSION_HEIGHT
if form_data.FILE_MAX_COUNT is not None
else request.app.state.config.FILE_MAX_COUNT
) )
request.app.state.config.ALLOWED_FILE_EXTENSIONS = ( request.app.state.config.ALLOWED_FILE_EXTENSIONS = (
form_data.ALLOWED_FILE_EXTENSIONS form_data.ALLOWED_FILE_EXTENSIONS
@ -1025,6 +1027,8 @@ async def update_rag_config(
# File upload settings # File upload settings
"FILE_MAX_SIZE": request.app.state.config.FILE_MAX_SIZE, "FILE_MAX_SIZE": request.app.state.config.FILE_MAX_SIZE,
"FILE_MAX_COUNT": request.app.state.config.FILE_MAX_COUNT, "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, "ALLOWED_FILE_EXTENSIONS": request.app.state.config.ALLOWED_FILE_EXTENSIONS,
# Integration settings # Integration settings
"ENABLE_GOOGLE_DRIVE_INTEGRATION": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, "ENABLE_GOOGLE_DRIVE_INTEGRATION": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,

View File

@ -1144,6 +1144,50 @@
</Tooltip> </Tooltip>
</div> </div>
</div> </div>
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Image Compression Width')}</div>
<div class="flex items-center relative">
<Tooltip
content={$i18n.t(
'The width in pixels to compress images to. Leave empty for no compression.'
)}
placement="top-start"
>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
type="number"
placeholder={$i18n.t('Leave empty for no compression')}
bind:value={RAGConfig.FILE_IMAGE_COMPRESSION_WIDTH}
autocomplete="off"
min="0"
/>
</Tooltip>
</div>
</div>
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Image Compression Height')}
</div>
<div class="flex items-center relative">
<Tooltip
content={$i18n.t(
'The height in pixels to compress images to. Leave empty for no compression.'
)}
placement="top-start"
>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
type="number"
placeholder={$i18n.t('Leave empty for no compression')}
bind:value={RAGConfig.FILE_IMAGE_COMPRESSION_HEIGHT}
autocomplete="off"
min="0"
/>
</Tooltip>
</div>
</div>
</div> </div>
<div class="mb-3"> <div class="mb-3">

View File

@ -110,9 +110,30 @@
reader.onload = async (event) => { reader.onload = async (event) => {
let imageUrl = event.target.result; let imageUrl = event.target.result;
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) { if ($settings?.imageCompression ?? false) {
const width = $settings?.imageCompressionSize?.width ?? null; width = $settings?.imageCompressionSize?.width ?? null;
const height = $settings?.imageCompressionSize?.height ?? 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) { if (width || height) {
imageUrl = await compressImage(imageUrl, width, height); imageUrl = await compressImage(imageUrl, width, height);

View File

@ -355,9 +355,30 @@
reader.onload = async (event) => { reader.onload = async (event) => {
let imageUrl = event.target.result; let imageUrl = event.target.result;
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) { if ($settings?.imageCompression ?? false) {
const width = $settings?.imageCompressionSize?.width ?? null; width = $settings?.imageCompressionSize?.width ?? null;
const height = $settings?.imageCompressionSize?.height ?? 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) { if (width || height) {
imageUrl = await compressImage(imageUrl, width, height); imageUrl = await compressImage(imageUrl, width, height);