fix: remove sharp image size limit

This commit is contained in:
mgt
2026-01-17 00:05:52 +08:00
parent a93904686e
commit 1f7bb7636b
5 changed files with 28 additions and 6 deletions

View File

@@ -4,11 +4,14 @@ import { rgbaToThumbHash } from 'thumbhash'
import { logger } from '../logger/index.js'
// 生成 blurhash基于缩略图数据保持长宽比
export async function generateBlurhash(thumbnailBuffer: Buffer): Promise<Uint8Array | null> {
export async function generateBlurhash(
thumbnailBuffer: Buffer,
limitInputPixels?: number | boolean,
): Promise<Uint8Array | null> {
try {
// 复用缩略图的 Sharp 实例来生成 blurhash
// 确保转换为 raw RGBA 格式
const { data, info } = await sharp(thumbnailBuffer)
const { data, info } = await sharp(thumbnailBuffer, { limitInputPixels })
.resize(100, 100, { fit: 'inside' })
.raw()
.ensureAlpha()

View File

@@ -79,7 +79,11 @@ async function processExistingThumbnail(photoId: string): Promise<ThumbnailResul
}
// 生成新的缩略图
async function generateNewThumbnail(imageBuffer: Buffer, photoId: string): Promise<ThumbnailResult> {
async function generateNewThumbnail(
imageBuffer: Buffer,
photoId: string,
limitInputPixels?: number | boolean,
): Promise<ThumbnailResult> {
const { thumbnailPath, thumbnailUrl } = getThumbnailPaths(photoId)
const log = getGlobalLoggers().thumbnail
@@ -88,7 +92,7 @@ async function generateNewThumbnail(imageBuffer: Buffer, photoId: string): Promi
try {
// 创建 Sharp 实例,复用于缩略图和 blurhash 生成
const sharpInstance = sharp(imageBuffer).rotate() // 自动根据 EXIF 旋转
const sharpInstance = sharp(imageBuffer, { limitInputPixels }).rotate() // 自动根据 EXIF 旋转
// 生成缩略图
const thumbnailBuffer = await sharpInstance
@@ -122,6 +126,7 @@ export async function generateThumbnailAndBlurhash(
imageBuffer: Buffer,
photoId: string,
forceRegenerate = false,
limitInputPixels?: number | boolean,
): Promise<ThumbnailResult> {
const thumbnailLog = getGlobalLoggers().thumbnail
@@ -139,7 +144,7 @@ export async function generateThumbnailAndBlurhash(
}
// 生成新的缩略图
return await generateNewThumbnail(imageBuffer, photoId)
return await generateNewThumbnail(imageBuffer, photoId, limitInputPixels)
} catch (error) {
thumbnailLog.error(`处理失败:${photoId}`, error)
return createFailureResult()

View File

@@ -10,6 +10,7 @@ import { extractExifData } from '../image/exif.js'
import { calculateHistogramAndAnalyzeTone } from '../image/histogram.js'
import { generateThumbnailAndBlurhash, thumbnailExists } from '../image/thumbnail.js'
import { workdir } from '../path.js'
import { getPhotoExecutionContext } from './execution-context.js'
import { getGlobalLoggers } from './logger-adapter.js'
import type { PhotoProcessorOptions } from './processor.js'
@@ -30,6 +31,8 @@ export async function processThumbnailAndBlurhash(
options: PhotoProcessorOptions,
): Promise<ThumbnailResult> {
const loggers = getGlobalLoggers()
const { builder } = getPhotoExecutionContext()
const { limitInputPixels } = builder.getConfig().system.processing
// 检查是否可以复用现有数据
if (
@@ -62,6 +65,7 @@ export async function processThumbnailAndBlurhash(
imageBuffer,
photoId,
options.isForceMode || options.isForceThumbnails,
limitInputPixels,
)
return {

View File

@@ -83,10 +83,12 @@ export async function preprocessImage(
*/
export async function processImageWithSharp(imageBuffer: Buffer, photoKey: string): Promise<ProcessedImageData | null> {
const loggers = getGlobalLoggers()
const { builder } = getPhotoExecutionContext()
const { limitInputPixels } = builder.getConfig().system.processing
try {
// 创建 Sharp 实例,复用于多个操作
let sharpInstance = sharp(imageBuffer)
let sharpInstance = sharp(imageBuffer, { limitInputPixels })
let processedBuffer = imageBuffer
// 处理 BMP

View File

@@ -20,6 +20,14 @@ export interface SystemProcessingSettings {
enableLivePhotoDetection: boolean
supportedFormats?: Set<string>
digestSuffixLength?: number
/**
* Do not process input images where the number of pixels (width x height) exceeds this limit.
* - `number`: An integral Number of pixels as the limit
* - `false` or `0`: Remove limit entirely
* - `true` or `undefined`: Use sharp's default limit of 268402689 (0x3FFF x 0x3FFF)
* @default undefined (uses sharp's default: 268402689)
*/
limitInputPixels?: number | boolean
}
export interface SystemObservabilitySettings {