Download and normalize painting images via sharp
Add sharp dep (libvips bindings) — fastest option for the per-image center-crop + Lanczos resize step. Pure-JS alternatives (jimp) and spawning ffmpeg per image were both ~5-10x slower in this hot loop. Add src/installer-rp/images.ts: - ytIdFromUrl: extracts the video ID from watch?v=, youtu.be/, and /shorts|embed/ URL forms - downloadImage: for YouTube URLs tries i.ytimg.com/vi/<id>/ maxresdefault.jpg first, falls back to hqdefault.jpg; plain image URLs go through a generic HTTP/HTTPS GET that follows 302s - normalizeToCover: center-crop to min(w,h), Lanczos resize down to 1024x1024 when larger, never upscales, writes PNG - coverFileName: returns cover_NN.png with zero-padded NN Wire step 2-3 of the install handler to download + normalize each image into <tempDir>/painting/cover_NN.png. Zip build (step 2-4) will pick those up next. Verified with synthetic 1200x800 and 2000x1500 buffers: small input stays 800x800 (no upscale), large input becomes 1024x1024. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import type { RpFetchedPack } from './types.js'
|
||||
import { ensureYtDlpExe } from './ytdlp.js'
|
||||
import { ensureFfmpegExe } from './ffmpeg.js'
|
||||
import { downloadMusicTrack } from './music.js'
|
||||
import { downloadImage, normalizeToCover, coverFileName } from './images.js'
|
||||
|
||||
interface RpInstallerState {
|
||||
manifestUrl: string
|
||||
@@ -187,10 +188,27 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string
|
||||
}
|
||||
|
||||
// 2-3. 사진 다운로드 + painting variant 정규화
|
||||
sendLog(`사진 다운로드 시작 (${pack.list.images.length}장) … (TODO)`)
|
||||
const paintingDir = path.join(tempRoot, 'painting')
|
||||
await fsp.mkdir(paintingDir, { recursive: true })
|
||||
sendLog(`사진 다운로드 시작 (${pack.list.images.length}장)`)
|
||||
for (let i = 0; i < pack.list.images.length; i++) {
|
||||
throwIfCancelled()
|
||||
sendLog(`${i + 1}번 사진 다운로드 중… (TODO)`)
|
||||
const entry = pack.list.images[i]
|
||||
sendLog(`${i + 1}번 사진 다운로드 중…`)
|
||||
let buf: Buffer
|
||||
try {
|
||||
buf = await downloadImage(entry.url)
|
||||
} catch (err) {
|
||||
throw new Error(`${i + 1}번 사진 다운로드 실패: ${(err as Error).message}`)
|
||||
}
|
||||
throwIfCancelled()
|
||||
const outPath = path.join(paintingDir, coverFileName(i + 1))
|
||||
try {
|
||||
await normalizeToCover(buf, outPath)
|
||||
} catch (err) {
|
||||
throw new Error(`${i + 1}번 사진 정규화 실패: ${(err as Error).message}`)
|
||||
}
|
||||
sendLog(`${i + 1}번 사진 완료: ${path.basename(outPath)}`)
|
||||
}
|
||||
|
||||
// 2-4. 리소스팩 zip 빌드
|
||||
|
||||
Reference in New Issue
Block a user