diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2025-04-27 04:10:32 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-26 11:10:32 -0700 |
commit | 1eb678cabd5816b81507d6387672593a1399bbf4 (patch) | |
tree | 37b7a59c9b7b6aea61036601516561e033ffae98 /src/lib/media | |
parent | ea718190ca3269ff8c9aac28257ce9e87c847f6c (diff) | |
download | voidsky-1eb678cabd5816b81507d6387672593a1399bbf4.tar.zst |
Optimize compressImage method to also use binary search (#7490)
* use binary search for compressImage * use binary search for doResize (mobile version) * use binary search for doResize (web version) * use safeDeleteAsync in compressImage --------- Co-authored-by: nguyen <nguyensvo123@gmail.com>
Diffstat (limited to 'src/lib/media')
-rw-r--r-- | src/lib/media/manip.ts | 27 | ||||
-rw-r--r-- | src/lib/media/manip.web.ts | 21 |
2 files changed, 36 insertions, 12 deletions
diff --git a/src/lib/media/manip.ts b/src/lib/media/manip.ts index 7f052068d..f6ef8347d 100644 --- a/src/lib/media/manip.ts +++ b/src/lib/media/manip.ts @@ -178,15 +178,20 @@ async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> { height: imageRes.height, }) - for (let i = 0; i < 9; i++) { - // nearest 10th - const quality = Math.round((1 - 0.1 * i) * 10) / 10 + let minQualityPercentage = 0 + let maxQualityPercentage = 101 // exclusive + let newDataUri + + while (maxQualityPercentage - minQualityPercentage > 1) { + const qualityPercentage = Math.round( + (maxQualityPercentage + minQualityPercentage) / 2, + ) const resizeRes = await manipulateAsync( localUri, [{resize: newDimensions}], { format: SaveFormat.JPEG, - compress: quality, + compress: qualityPercentage / 100, }, ) @@ -198,8 +203,8 @@ async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> { } if (fileInfo.size < opts.maxSize) { - safeDeleteAsync(imageRes.uri) - return { + minQualityPercentage = qualityPercentage + newDataUri = { path: normalizePath(resizeRes.uri), mime: 'image/jpeg', size: fileInfo.size, @@ -207,9 +212,17 @@ async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> { height: resizeRes.height, } } else { - safeDeleteAsync(resizeRes.uri) + maxQualityPercentage = qualityPercentage } + + safeDeleteAsync(resizeRes.uri) } + + if (newDataUri) { + safeDeleteAsync(imageRes.uri) + return newDataUri + } + throw new Error( `This image is too big! We couldn't compress it down to ${opts.maxSize} bytes`, ) diff --git a/src/lib/media/manip.web.ts b/src/lib/media/manip.web.ts index 4761f2fe0..ffef7314d 100644 --- a/src/lib/media/manip.web.ts +++ b/src/lib/media/manip.web.ts @@ -72,17 +72,28 @@ interface DoResizeOpts { async function doResize(dataUri: string, opts: DoResizeOpts): Promise<RNImage> { let newDataUri - for (let i = 0; i <= 10; i++) { - newDataUri = await createResizedImage(dataUri, { + let minQualityPercentage = 0 + let maxQualityPercentage = 101 //exclusive + + while (maxQualityPercentage - minQualityPercentage > 1) { + const qualityPercentage = Math.round( + (maxQualityPercentage + minQualityPercentage) / 2, + ) + const tempDataUri = await createResizedImage(dataUri, { width: opts.width, height: opts.height, - quality: 1 - i * 0.1, + quality: qualityPercentage / 100, mode: opts.mode, }) - if (getDataUriSize(newDataUri) < opts.maxSize) { - break + + if (getDataUriSize(tempDataUri) < opts.maxSize) { + minQualityPercentage = qualityPercentage + newDataUri = tempDataUri + } else { + maxQualityPercentage = qualityPercentage } } + if (!newDataUri) { throw new Error('Failed to compress image') } |