@@ -3,13 +3,29 @@ import path from 'node:path'
33
44import { isNil , noop } from 'es-toolkit'
55import type { ExifDateTime , Tags } from 'exiftool-vendored'
6- import { exiftool } from 'exiftool-vendored'
7- import type { Metadata } from 'sharp'
8- import sharp from 'sharp'
6+ import { ExifTool } from 'exiftool-vendored'
97
108import { getGlobalLoggers } from '../photo/logger-adapter.js'
119import type { PickedExif } from '../types/photo.js'
1210
11+ const exiftool = new ExifTool ( {
12+ ...( process . env . EXIFTOOL_PATH ? { exiftoolPath : process . env . EXIFTOOL_PATH } : { } ) ,
13+ taskTimeoutMillis : 30000 ,
14+ } )
15+
16+ let isExiftoolClosed = false
17+ const closeExiftool = ( ) => {
18+ if ( isExiftoolClosed ) {
19+ return
20+ }
21+ isExiftoolClosed = true
22+ exiftool . end ( ) . catch ( noop )
23+ }
24+
25+ process . once ( 'beforeExit' , closeExiftool )
26+ process . once ( 'SIGINT' , closeExiftool )
27+ process . once ( 'SIGTERM' , closeExiftool )
28+
1329// 提取 EXIF 数据
1430export async function extractExifData ( imageBuffer : Buffer , originalBuffer ?: Buffer ) : Promise < PickedExif | null > {
1531 const log = getGlobalLoggers ( ) . exif
@@ -18,29 +34,12 @@ export async function extractExifData(imageBuffer: Buffer, originalBuffer?: Buff
1834 const tempImagePath = path . resolve ( '/tmp/image_process' , `${ crypto . randomUUID ( ) } .jpg` )
1935
2036 try {
21- log . info ( '开始提取 EXIF 数据' )
22-
23- // 首先尝试从处理后的图片中提取 EXIF
24- let metadata = await sharp ( imageBuffer ) . metadata ( )
25-
26- // 如果处理后的图片没有 EXIF 数据,且提供了原始 buffer,尝试从原始图片提取
27- if ( ! metadata . exif && originalBuffer ) {
28- log . info ( '处理后的图片缺少 EXIF 数据,尝试从原始图片提取' )
29- try {
30- metadata = await sharp ( originalBuffer ) . metadata ( )
31- } catch ( error ) {
32- log . warn ( '从原始图片提取 EXIF 失败,可能是不支持的格式:' , error )
33- }
34- }
35-
36- if ( ! metadata . exif ) {
37- log . warn ( '未找到 EXIF 数据' )
38- return null
39- }
40-
4137 await writeFile ( tempImagePath , originalBuffer || imageBuffer )
38+
39+ log . info ( `开始提取 EXIF 数据, 文件路径: ${ tempImagePath } ` )
4240 const exifData = await exiftool . read ( tempImagePath )
43- const result = handleExifData ( exifData , metadata )
41+
42+ const result = handleExifData ( exifData )
4443
4544 if ( ! exifData ) {
4645 log . warn ( 'EXIF 数据解析失败' )
@@ -135,7 +134,7 @@ const pickKeys: Array<keyof Tags | (string & {})> = [
135134 'MicroVideoOffset' ,
136135 'MicroVideoPresentationTimestampUs' ,
137136]
138- function handleExifData ( exifData : Tags , metadata : Metadata ) : PickedExif {
137+ function handleExifData ( exifData : Tags ) : PickedExif {
139138 const date = {
140139 DateTimeOriginal : formatExifDate ( exifData . DateTimeOriginal ) ,
141140 DateTimeDigitized : formatExifDate ( exifData . DateTimeDigitized ) ,
@@ -177,8 +176,8 @@ function handleExifData(exifData: Tags, metadata: Metadata): PickedExif {
177176 }
178177 }
179178 const size = {
180- ImageWidth : exifData . ExifImageWidth || metadata . width ,
181- ImageHeight : exifData . ExifImageHeight || metadata . height ,
179+ ImageWidth : exifData . ExifImageWidth ,
180+ ImageHeight : exifData . ExifImageHeight ,
182181 }
183182 const result : any = structuredClone ( exifData )
184183 for ( const key in result ) {
0 commit comments