From 06b2c60a4ae77dca0eb18446d73eb0f0d1131bc5 Mon Sep 17 00:00:00 2001 From: evlist Date: Sat, 22 Apr 2023 18:04:20 +0200 Subject: [PATCH] Resize refactoring to create downsized image and thumbnails in one run --- src/components/import/ImportSingleFile.tsx | 7 +- src/lib/image.ts | 94 +++++++++++----------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/components/import/ImportSingleFile.tsx b/src/components/import/ImportSingleFile.tsx index 42acb41..525ca8c 100644 --- a/src/components/import/ImportSingleFile.tsx +++ b/src/components/import/ImportSingleFile.tsx @@ -21,7 +21,7 @@ import { } from '@capacitor/filesystem'; import piexif from 'piexifjs'; import { getDate, getGps } from '../../lib/exif'; -import { resize } from '../../lib/image'; +import { downsize } from '../../lib/image'; interface Props { file: File; @@ -118,7 +118,10 @@ const ImportSingleFile: Component = ({ file: file }) => { const id = exifObj.Exif[piexif.ExifIFD.ImageUniqueID]; const gps = getGps(exifObj); const date = getDate(exifObj); - const thumbnailUrl = await resize(reader.result, 128); + const [downsizedUrl, thumbnailUrl] = await downsize( + reader.result, + [1024, 128] + ); // const gps = tags.gps; // const image = await Image.load(reader.result); // const thumbnail = image.resize({ diff --git a/src/lib/image.ts b/src/lib/image.ts index fae1945..c222a91 100644 --- a/src/lib/image.ts +++ b/src/lib/image.ts @@ -1,59 +1,61 @@ -export const resize = (imageUrl: string, maxSize: number) => { +import { cloneDeep } from 'lodash'; + +const downsizeCanvas = (canvas: HTMLCanvasElement, maxSize: number) => { + const currentMaxSize = Math.max(canvas.width, canvas.height); + const ratio = currentMaxSize / maxSize; + const targetWidth = canvas.width / ratio; + const targetHeight = canvas.height / ratio; + const nbStepsReal = Math.log2(ratio); + const nbSteps = Math.floor(nbStepsReal); + let width = canvas.width; + let height = canvas.height; + const canvasCtx = canvas.getContext('2d'); + + for (let i = 0; i < nbSteps; i++) { + width = width / 2; + height = height / 2; + canvasCtx?.drawImage(canvas, 0, 0, canvas.width / 2, canvas.height / 2); + } + + const finalCanvas = document.createElement('canvas'); + finalCanvas.height = targetHeight; + finalCanvas.width = targetWidth; + const finalCanvasCtx = finalCanvas.getContext('2d'); + finalCanvasCtx?.drawImage( + canvas, + 0, + 0, + width, + height, + 0, + 0, + targetWidth, + targetHeight + ); + + return finalCanvas; +}; + +export const downsize = (imageUrl: string, maxSizes: number[]) => { let resolver = (resizedImageUrl: any) => {}; const img = document.createElement('img'); img.onload = () => { - const currentMaxSize = Math.max(img.width, img.height); - const ratio = currentMaxSize / maxSize; - const targetWidth = img.width / ratio; - const targetHeight = img.height / ratio; - const nbStepsReal = Math.log2(ratio); - const nbSteps = Math.floor(nbStepsReal); - - const canvas = document.createElement('canvas'); + let canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; const canvasCtx = canvas.getContext('2d'); + canvasCtx?.drawImage(img, 0, 0); - let src: any = img; - let width = img.width; - let height = img.height; - for (let i = 0; i < nbSteps; i++) { - width = width / 2; - height = height / 2; - canvasCtx?.drawImage(src, 0, 0, canvas.width / 2, canvas.height / 2); - src = canvas; - console.log({ - caller: 'resize', - width, - height, - targetHeight, - targetWidth, - i, - }); - } + img.remove(); - const finalCanvas = document.createElement('canvas'); - finalCanvas.height = targetHeight; - finalCanvas.width = targetWidth; - const finalCanvasCtx = finalCanvas.getContext('2d'); - finalCanvasCtx?.drawImage( - canvas, - 0, - 0, - width, - height, - 0, - 0, - targetWidth, - targetHeight - ); + const canvases = maxSizes.map((maxSize: number) => { + canvas = downsizeCanvas(canvas, maxSize); + return canvas.toDataURL('image/jpeg'); + }); - const imageUrl = finalCanvas.toDataURL('image/jpeg'); - canvas.remove(); - finalCanvas.remove(); - - resolver(imageUrl); + resolver(canvases); }; + img.src = imageUrl; return new Promise((resolve, reject) => { resolver = resolve;