mirror of
https://github.com/Afilmory/afilmory
synced 2026-04-25 15:25:03 +00:00
fix: remove sharp image size limit
This commit is contained in:
@@ -4,11 +4,14 @@ import { rgbaToThumbHash } from 'thumbhash'
|
|||||||
import { logger } from '../logger/index.js'
|
import { logger } from '../logger/index.js'
|
||||||
|
|
||||||
// 生成 blurhash(基于缩略图数据,保持长宽比)
|
// 生成 blurhash(基于缩略图数据,保持长宽比)
|
||||||
export async function generateBlurhash(thumbnailBuffer: Buffer): Promise<Uint8Array | null> {
|
export async function generateBlurhash(
|
||||||
|
thumbnailBuffer: Buffer,
|
||||||
|
limitInputPixels?: number | boolean,
|
||||||
|
): Promise<Uint8Array | null> {
|
||||||
try {
|
try {
|
||||||
// 复用缩略图的 Sharp 实例来生成 blurhash
|
// 复用缩略图的 Sharp 实例来生成 blurhash
|
||||||
// 确保转换为 raw RGBA 格式
|
// 确保转换为 raw RGBA 格式
|
||||||
const { data, info } = await sharp(thumbnailBuffer)
|
const { data, info } = await sharp(thumbnailBuffer, { limitInputPixels })
|
||||||
.resize(100, 100, { fit: 'inside' })
|
.resize(100, 100, { fit: 'inside' })
|
||||||
.raw()
|
.raw()
|
||||||
.ensureAlpha()
|
.ensureAlpha()
|
||||||
|
|||||||
@@ -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 { thumbnailPath, thumbnailUrl } = getThumbnailPaths(photoId)
|
||||||
|
|
||||||
const log = getGlobalLoggers().thumbnail
|
const log = getGlobalLoggers().thumbnail
|
||||||
@@ -88,7 +92,7 @@ async function generateNewThumbnail(imageBuffer: Buffer, photoId: string): Promi
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 创建 Sharp 实例,复用于缩略图和 blurhash 生成
|
// 创建 Sharp 实例,复用于缩略图和 blurhash 生成
|
||||||
const sharpInstance = sharp(imageBuffer).rotate() // 自动根据 EXIF 旋转
|
const sharpInstance = sharp(imageBuffer, { limitInputPixels }).rotate() // 自动根据 EXIF 旋转
|
||||||
|
|
||||||
// 生成缩略图
|
// 生成缩略图
|
||||||
const thumbnailBuffer = await sharpInstance
|
const thumbnailBuffer = await sharpInstance
|
||||||
@@ -122,6 +126,7 @@ export async function generateThumbnailAndBlurhash(
|
|||||||
imageBuffer: Buffer,
|
imageBuffer: Buffer,
|
||||||
photoId: string,
|
photoId: string,
|
||||||
forceRegenerate = false,
|
forceRegenerate = false,
|
||||||
|
limitInputPixels?: number | boolean,
|
||||||
): Promise<ThumbnailResult> {
|
): Promise<ThumbnailResult> {
|
||||||
const thumbnailLog = getGlobalLoggers().thumbnail
|
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) {
|
} catch (error) {
|
||||||
thumbnailLog.error(`处理失败:${photoId}`, error)
|
thumbnailLog.error(`处理失败:${photoId}`, error)
|
||||||
return createFailureResult()
|
return createFailureResult()
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { extractExifData } from '../image/exif.js'
|
|||||||
import { calculateHistogramAndAnalyzeTone } from '../image/histogram.js'
|
import { calculateHistogramAndAnalyzeTone } from '../image/histogram.js'
|
||||||
import { generateThumbnailAndBlurhash, thumbnailExists } from '../image/thumbnail.js'
|
import { generateThumbnailAndBlurhash, thumbnailExists } from '../image/thumbnail.js'
|
||||||
import { workdir } from '../path.js'
|
import { workdir } from '../path.js'
|
||||||
|
import { getPhotoExecutionContext } from './execution-context.js'
|
||||||
import { getGlobalLoggers } from './logger-adapter.js'
|
import { getGlobalLoggers } from './logger-adapter.js'
|
||||||
import type { PhotoProcessorOptions } from './processor.js'
|
import type { PhotoProcessorOptions } from './processor.js'
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ export async function processThumbnailAndBlurhash(
|
|||||||
options: PhotoProcessorOptions,
|
options: PhotoProcessorOptions,
|
||||||
): Promise<ThumbnailResult> {
|
): Promise<ThumbnailResult> {
|
||||||
const loggers = getGlobalLoggers()
|
const loggers = getGlobalLoggers()
|
||||||
|
const { builder } = getPhotoExecutionContext()
|
||||||
|
const { limitInputPixels } = builder.getConfig().system.processing
|
||||||
|
|
||||||
// 检查是否可以复用现有数据
|
// 检查是否可以复用现有数据
|
||||||
if (
|
if (
|
||||||
@@ -62,6 +65,7 @@ export async function processThumbnailAndBlurhash(
|
|||||||
imageBuffer,
|
imageBuffer,
|
||||||
photoId,
|
photoId,
|
||||||
options.isForceMode || options.isForceThumbnails,
|
options.isForceMode || options.isForceThumbnails,
|
||||||
|
limitInputPixels,
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -83,10 +83,12 @@ export async function preprocessImage(
|
|||||||
*/
|
*/
|
||||||
export async function processImageWithSharp(imageBuffer: Buffer, photoKey: string): Promise<ProcessedImageData | null> {
|
export async function processImageWithSharp(imageBuffer: Buffer, photoKey: string): Promise<ProcessedImageData | null> {
|
||||||
const loggers = getGlobalLoggers()
|
const loggers = getGlobalLoggers()
|
||||||
|
const { builder } = getPhotoExecutionContext()
|
||||||
|
const { limitInputPixels } = builder.getConfig().system.processing
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 创建 Sharp 实例,复用于多个操作
|
// 创建 Sharp 实例,复用于多个操作
|
||||||
let sharpInstance = sharp(imageBuffer)
|
let sharpInstance = sharp(imageBuffer, { limitInputPixels })
|
||||||
let processedBuffer = imageBuffer
|
let processedBuffer = imageBuffer
|
||||||
|
|
||||||
// 处理 BMP
|
// 处理 BMP
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ export interface SystemProcessingSettings {
|
|||||||
enableLivePhotoDetection: boolean
|
enableLivePhotoDetection: boolean
|
||||||
supportedFormats?: Set<string>
|
supportedFormats?: Set<string>
|
||||||
digestSuffixLength?: number
|
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 {
|
export interface SystemObservabilitySettings {
|
||||||
|
|||||||
Reference in New Issue
Block a user