Here's the idea: after the user takes a picture, the photo will be uploaded to Firebase twice -- one uncompressed (i.e. full 2160p resolution -- ~3mb file), and another in compressed format (i.e. 400p only -- ~250kb).
Currently, FlutterFlow will only allow me to upload in either full resolution OR reduced resolution.
I also tried creating a custom action that should take the upload URL and produce a copy in smaller resolution, but I was not successful in making a working code. (I'm still figuring out how to make this work.)
The code looks something like this:
// Automatic FlutterFlow imports import '/backend/backend.dart'; import '/actions/actions.dart' as action_blocks; import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; import '/custom_code/actions/index.dart'; // Imports other custom actions import '/flutter_flow/custom_functions.dart'; // Imports custom functions import 'package:flutter/material.dart'; // Begin custom action code // DO NOT REMOVE OR MODIFY THE CODE ABOVE! // Import necessary packages import 'dart:io'; import 'package:image/image.dart' as img; import 'package:path_provider/path_provider.dart'; import 'package:firebase_storage/firebase_storage.dart'; Future<String?> compressImageFromURL(String inputImageURL) async { try { // Get the image from the URL final response = await HttpClient().getUrl(Uri.parse(inputImageURL)); final bytes = await response.close(); final originalImage = img.decodeImage((await bytes.toList()) as Uint8List); // Check if the image was successfully loaded if (originalImage == null) { throw Exception("Failed to decode the original image"); } // Compress the image to 400px final compressedImage = img.copyResize(originalImage, width: 400); // Save the compressed image to local storage final tempDir = await getTemporaryDirectory(); final tempPath = '${tempDir.path}/${DateTime.now().millisecondsSinceEpoch}.jpg'; File(tempPath)..writeAsBytesSync(img.encodeJpg(compressedImage)); // Upload the compressed image to Firebase Storage final storageRef = FirebaseStorage.instance .ref() .child('images/${DateTime.now().millisecondsSinceEpoch}.jpg'); final uploadTask = storageRef.putFile(File(tempPath)); await uploadTask; // Get the download URL of the compressed image final downloadURL = await storageRef.getDownloadURL(); // Delete the local file after successful upload File(tempPath).delete(); // Return the download URL as the image path return downloadURL; } catch (error, stackTrace) { print("Error during image compression and upload: $error"); print("Stack trace: $stackTrace"); return null; } }
Any ideas how I can implement this?