Fix image compression for avis and banner images

zio/stable
Paul Frazee 2023-01-12 15:07:32 -06:00
parent 7215da135b
commit 29020fbcee
3 changed files with 37 additions and 19 deletions

View File

@ -1,6 +1,5 @@
import RNFetchBlob from 'rn-fetch-blob' import RNFetchBlob from 'rn-fetch-blob'
import ImageResizer from '@bam.tech/react-native-image-resizer' import ImageResizer from '@bam.tech/react-native-image-resizer'
import {Image as PickedImage} from 'react-native-image-crop-picker'
export interface DownloadAndResizeOpts { export interface DownloadAndResizeOpts {
uri: string uri: string
@ -11,6 +10,14 @@ export interface DownloadAndResizeOpts {
timeout: number timeout: number
} }
export interface Image {
path: string
mime: string
size: number
width: number
height: number
}
export async function downloadAndResize(opts: DownloadAndResizeOpts) { export async function downloadAndResize(opts: DownloadAndResizeOpts) {
let appendExt let appendExt
try { try {
@ -58,7 +65,10 @@ export interface ResizeOpts {
maxSize: number maxSize: number
} }
export async function resize(localUri: string, opts: ResizeOpts) { export async function resize(
localUri: string,
opts: ResizeOpts,
): Promise<Image> {
for (let i = 0; i < 9; i++) { for (let i = 0; i < 9; i++) {
const quality = 1.0 - i / 10 const quality = 1.0 - i / 10
const resizeRes = await ImageResizer.createResizedImage( const resizeRes = await ImageResizer.createResizedImage(
@ -73,7 +83,13 @@ export async function resize(localUri: string, opts: ResizeOpts) {
{mode: opts.mode}, {mode: opts.mode},
) )
if (resizeRes.size < opts.maxSize) { if (resizeRes.size < opts.maxSize) {
return resizeRes return {
path: resizeRes.path,
mime: 'image/jpeg',
size: resizeRes.size,
width: resizeRes.width,
height: resizeRes.height,
}
} }
} }
throw new Error( throw new Error(
@ -81,16 +97,18 @@ export async function resize(localUri: string, opts: ResizeOpts) {
) )
} }
export async function compressIfNeeded(img: PickedImage, maxSize: number) { export async function compressIfNeeded(
img: Image,
maxSize: number,
): Promise<Image> {
const origUri = `file://${img.path}` const origUri = `file://${img.path}`
if (img.size < maxSize) { if (img.size < maxSize) {
return origUri return img
} }
const resizeRez = await resize(origUri, { return await resize(origUri, {
width: img.width, width: img.width,
height: img.height, height: img.height,
mode: 'stretch', mode: 'stretch',
maxSize, maxSize,
}) })
return resizeRez.uri
} }

View File

@ -36,8 +36,8 @@ export const PhotoCarouselPicker = ({
cropping: true, cropping: true,
...IMAGE_PARAMS, ...IMAGE_PARAMS,
}) })
const uri = await compressIfNeeded(cameraRes, 300000) const img = await compressIfNeeded(cameraRes, 300000)
onSelectPhotos([uri, ...selectedPhotos]) onSelectPhotos([img.path, ...selectedPhotos])
} catch (err: any) { } catch (err: any) {
// ignore // ignore
store.log.warn('Error using camera', err) store.log.warn('Error using camera', err)
@ -52,8 +52,8 @@ export const PhotoCarouselPicker = ({
path: uri, path: uri,
...IMAGE_PARAMS, ...IMAGE_PARAMS,
}) })
const finalUri = await compressIfNeeded(cropperRes, 300000) const img = await compressIfNeeded(cropperRes, 300000)
onSelectPhotos([finalUri, ...selectedPhotos]) onSelectPhotos([img.path, ...selectedPhotos])
} catch (err: any) { } catch (err: any) {
// ignore // ignore
store.log.warn('Error selecting photo', err) store.log.warn('Error selecting photo', err)
@ -76,8 +76,8 @@ export const PhotoCarouselPicker = ({
path: image.path, path: image.path,
...IMAGE_PARAMS, ...IMAGE_PARAMS,
}) })
const finalUri = await compressIfNeeded(cropperRes, 300000) const finalImg = await compressIfNeeded(cropperRes, 300000)
result.push(finalUri) result.push(finalImg.path)
} }
onSelectPhotos([...result, ...selectedPhotos]) onSelectPhotos([...result, ...selectedPhotos])
}) })

View File

@ -55,18 +55,18 @@ export function Component({
} }
const onSelectNewAvatar = async (img: PickedImage) => { const onSelectNewAvatar = async (img: PickedImage) => {
try { try {
setNewUserAvatar(img) const finalImg = await compressIfNeeded(img, 300000)
const uri = await compressIfNeeded(img, 300000) setNewUserAvatar(finalImg)
setUserAvatar(uri) setUserAvatar(finalImg.path)
} catch (e: any) { } catch (e: any) {
setError(e.message || e.toString()) setError(e.message || e.toString())
} }
} }
const onSelectNewBanner = async (img: PickedImage) => { const onSelectNewBanner = async (img: PickedImage) => {
try { try {
setNewUserBanner(img) const finalImg = await compressIfNeeded(img, 500000)
const uri = await compressIfNeeded(img, 500000) setNewUserBanner(finalImg)
setUserBanner(uri) setUserBanner(finalImg.path)
} catch (e: any) { } catch (e: any) {
setError(e.message || e.toString()) setError(e.message || e.toString())
} }