Home > Mobile >  Flutter App is getting crashed when picking multiple images from gallery and displaying on to the sc
Flutter App is getting crashed when picking multiple images from gallery and displaying on to the sc

Time:08-18

Flutter App is getting crashed when picking multiple images from gallery and displaying on to the screen. Is there a way to compress the pictures before displaying them? How to compress multiple pictures at a time? Can we display images as thumbnails to load faster and smoother?

I am currently using image picker to pick multiple images and store them in a list. How to compress all the selected pictures in the list and display them without crashing? Please help me out!

List<XFile> picturesList = [];

  pickImages() async {
    try {
      final List<XFile>? pickedImages = await ImagePicker().pickMultiImage();
      if (pickedImages!.isNotEmpty) {
        picturesList.addAll(pickedImages);
        notifyListeners();
      }
    } catch (e) {
      debugPrint(e.toString());
    }
  }
class ImagesGrid extends StatelessWidget {
  const ImagesGrid({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
            onPressed: () {
              pickImages();
            },
            child: const Text('Pick Images')),
        SizedBox(
          height: 600,
          child: GridView.builder(
            padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                childAspectRatio: 1,
                mainAxisSpacing: 5.0,
                crossAxisSpacing: 5.0,
                crossAxisCount: 4),
            itemCount: picturesList.length,
            itemBuilder: (context, index) {
              return SizedBox(
                width: 100,
                height: 100,
                child: Image.file(
                  File(picturesList[index].path),
                  fit: BoxFit.cover,
                ),
              );
            },
          ),
        ),
      ],
    );
  }
}

CodePudding user response:

You can specify quality of images while picking

try {
          final List<XFile>? pickedFileList = await _picker.pickMultiImage(
             maxHeight: 480, maxWidth: 640
            imageQuality: quality,//<---this will compress the images
          );
          setState(() {
            _imageFileList = pickedFileList;
          });
        } catch (e) {
          setState(() {
            _pickImageError = e;
          });

CodePudding user response:

Found the solution to pick multiple images from phone internal storage and compressing the selected pictures on the go and displaying. Used File picker instead of Image picker to pick the images and Flutter Native Image package to compress the pictures. This is quite faster to load pictures also app isn't crashing even though loading original high resolution pictures as well.

class ImagesGrid extends StatefulWidget {
  const ImagesGrid({Key? key}) : super(key: key);

  @override
  State<ImagesGrid> createState() => _ImagesGridState();
}

class _ImagesGridState extends State<ImagesGrid> {
  List<String> selectedImages = [];
  List<String> temporaryImages = [];
  List<File> compressedImages = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Compress Images')),
      body: compressedImages.isNotEmpty
          ? Column(
              children: [
                SizedBox(
                  height: 700,
                  child: GridView.builder(
                    padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
                    gridDelegate:
                        const SliverGridDelegateWithFixedCrossAxisCount(
                            childAspectRatio: 1,
                            mainAxisSpacing: 5.0,
                            crossAxisSpacing: 5.0,
                            crossAxisCount: 4),
                    itemCount: compressedImages.length,
                    itemBuilder: (context, index) {
                      return SizedBox(
                        width: 100,
                        height: 100,
                        child: Image.file(
                          compressedImages[index],
                          fit: BoxFit.cover,
                        ),
                      );
                    },
                  ),
                ),
                ElevatedButton(
                    onPressed: () => pickImages(),
                    child: const Text('Pick Images')),
              ],
            )
          : InkWell(
              onTap: () => pickImages(),
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: const [
                    Icon(Icons.add_a_photo),
                    SizedBox(height: 10),
                    Text('Tap anywhere to pick images')
                  ],
                ),
              ),
            ),
    );
  }

  pickImages() async {
    try {
      final pickedImages = await FilePicker.platform
          .pickFiles(type: FileType.image, allowMultiple: true);
      if (pickedImages != null && pickedImages.files.isNotEmpty) {
        setState(() {});
        final image = pickedImages.files.map((e) => e.path!);
        selectedImages.addAll(image);
        temporaryImages.addAll(image);

        for (int i = 0; i < temporaryImages.length; i  ) {
          compressImage(temporaryImages[i]);
        }

        Future.delayed(
            const Duration(seconds: 1), () => temporaryImages.clear());
      }
    } on PlatformException catch (e) {
      debugPrint(e.toString());
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  compressImage(path) async {
    if (selectedImages.isEmpty) return;
    ImageProperties properties =
        await FlutterNativeImage.getImageProperties(path);
    await FlutterNativeImage.compressImage(path,
            quality: 50,
            targetWidth: 600,
            targetHeight:
                (properties.height! * 600 / (properties.width)!).round())
        .then((response) => setState(() => compressedImages.add(response)))
        .catchError((e) => debugPrint(e));
  }
}
  • Related