gongxiangp2/lib/brand-knowledge-image-browser.ts

67 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
BRAND_KNOWLEDGE_MAX_PREVIEW_IMAGE_BYTES,
BRAND_KNOWLEDGE_MAX_PREVIEW_SLICE_BYTES,
BRAND_KNOWLEDGE_MAX_PREVIEW_SLICE_COUNT,
} from '@/lib/brand-knowledge-file-types'
import {
preparePerformanceSurveyImagesInBrowser,
type PerformanceSurveyBrowserProcessedImage,
} from '@/lib/performance-survey-image-browser'
import {
BRAND_KNOWLEDGE_LEGACY_SERVER_MAX_PIXELS,
PERFORMANCE_SURVEY_BROWSER_SOURCE_LIMITS,
readPerformanceSurveySourceImageDimensions,
} from '@/lib/performance-survey-image-source-guard'
export type BrandKnowledgeBrowserPreviewSlice = PerformanceSurveyBrowserProcessedImage & {
kind: 'slice'
}
export async function prepareBrandKnowledgePreviewInBrowser(
file: File,
onProgress?: (label: string) => void,
options: { signal?: AbortSignal; timeoutMs?: number } = {},
): Promise<BrandKnowledgeBrowserPreviewSlice[]> {
const processed = await preparePerformanceSurveyImagesInBrowser(
[file],
onProgress,
{
profile: 'brand_knowledge_preview',
signal: options.signal,
timeoutMs: options.timeoutMs,
},
)
const slices = processed.filter(
(item): item is BrandKnowledgeBrowserPreviewSlice => item.kind === 'slice',
)
if (slices.length === 0) throw new Error('浏览器未生成品牌知识预览切片')
if (slices.length > BRAND_KNOWLEDGE_MAX_PREVIEW_SLICE_COUNT) {
throw new Error(`预览图处理后超过 ${BRAND_KNOWLEDGE_MAX_PREVIEW_SLICE_COUNT} 个切片`)
}
if (slices.some((slice) => slice.file.size <= 0 || slice.file.size > BRAND_KNOWLEDGE_MAX_PREVIEW_SLICE_BYTES)) {
throw new Error('预览图处理后的单个切片过大,请先压缩图片后重试')
}
const totalBytes = slices.reduce((sum, slice) => sum + slice.file.size, 0)
if (totalBytes > BRAND_KNOWLEDGE_MAX_PREVIEW_IMAGE_BYTES) {
throw new Error('预览图处理后的切片总大小超过 50MB,请先压缩图片后重试')
}
return slices
}
export async function canUseBrandKnowledgeLegacyServerPreview(file: File) {
let bytes = new Uint8Array(
await file.slice(0, PERFORMANCE_SURVEY_BROWSER_SOURCE_LIMITS.headerReadBytes).arrayBuffer(),
)
let dimensions = readPerformanceSurveySourceImageDimensions(bytes)
if (!dimensions && file.size > bytes.byteLength) {
bytes = new Uint8Array(
await file.slice(0, PERFORMANCE_SURVEY_BROWSER_SOURCE_LIMITS.extendedHeaderReadBytes).arrayBuffer(),
)
dimensions = readPerformanceSurveySourceImageDimensions(bytes)
}
if (!dimensions) return false
return dimensions.width <= PERFORMANCE_SURVEY_BROWSER_SOURCE_LIMITS.maxWidth
&& dimensions.height <= 90_000
&& dimensions.width * dimensions.height <= BRAND_KNOWLEDGE_LEGACY_SERVER_MAX_PIXELS
}