Mobile app will not load image

I have a mobile app that takes a photo using the camera component. I then preview the image in the image component. Everything works fine unless I try to compress the image and preview. The compressed image will display in the web editor view but when I push to my mobile device it does not work.

Here is the compression code.

function getImage(dataUrl)
{
    return new Promise((resolve, reject) => {
        const image = new Image();
        image.src = dataUrl;
        image.onload = () => {
            resolve(image);
        };
        image.onerror = (el, err) => {
            reject(err.error);
        };
    });
}

async function downscaleImage(
        dataUrl,  
        imageType,  // e.g. 'image/jpeg'
        resolution,  // max width/height in pixels
        quality   // e.g. 0.9 = 90% quality
    ) {

    // Create a temporary image so that we can compute the height of the image.
    const image = await getImage(dataUrl);
    const oldWidth = image.naturalWidth;
    const oldHeight = image.naturalHeight;
    console.log('dims', oldWidth, oldHeight);

    const longestDimension = oldWidth > oldHeight ? 'width' : 'height';
    const currentRes = longestDimension == 'width' ? oldWidth : oldHeight;
    console.log('longest dim', longestDimension, currentRes);

    if (currentRes > resolution) {
        console.log('need to resize...');

        // Calculate new dimensions
        const newSize = longestDimension == 'width' ? Math.floor(oldHeight / oldWidth * resolution) : Math.floor(oldWidth / oldHeight * resolution);
        const newWidth = longestDimension == 'width' ? resolution : newSize;
        const newHeight = longestDimension == 'height' ? resolution : newSize;
        console.log('new width / height', newWidth, newHeight);

        // Create a temporary canvas to draw the downscaled image on.
        const canvas = document.createElement('canvas');
        canvas.width = newWidth;
        canvas.height = newHeight;

        // Draw the downscaled image on the canvas and return the new data URL.
        const ctx = canvas.getContext('2d');
        ctx.drawImage(image, 0, 0, newWidth, newHeight);
        const newDataUrl = canvas.toDataURL(imageType, quality);
        return newDataUrl;
    }
    else {
        return dataUrl;
    }

}

let dataUrl = 'data:'+camera1.files['0'].type+';base64,'+camera1.value[0];
let imageType = camera1.files[0].type
let resolution = 400
let quality = .8


let ds = downscaleImage(
        dataUrl,  
        imageType,  // e.g. 'image/jpeg'
        resolution,  // max width/height in pixels
        quality   // e.g. 0.9 = 90% quality
    )

return ds;

I then use a transformer to strip the string.

return data.split(',').pop();

this works on the website and mobile editor but not on the actual mobile app.

Hey @nroeder! :slight_smile:

Mind sharing your app so we can test this out on our end? I can't seem to get your query to run in a JS query (runs forever)

Shawn said it is a limitation in React Native on iOS. Do you have an alternative method to compress an image that does not use the Image()

Not that I’m aware of. I think zipping an image in JS from a Retool Mobile app is probably not something we can easily support (_for now_ :crossed_fingers:), but I’ll put in a feature request for the Mobile team now!

1 Like

Sorry when i say compress I mean reduce size, so take it from a 1.5mb image.png to a 200kb image.png.