Poor image quality in saving image from a screenshot ( flutter )

578

So the whole goal of your app is to create a collage off images and save them to the disk? (maybe useful if you'd explain this first)

I would suggest either limiting the size of the "canvas" area, or resize it before saving it. You could also experiment with various compression algorithms, like JPEG, and their parameters. Not sure about the quality off FlutterNativeImage. Maybe you could look into some other packages? I see the flutter_image_compress package has a lot of likes.

Share:
578
Admin
Author by

Admin

Updated on December 31, 2022

Comments

  • Admin
    Admin about 1 year

    I have a screen which lets users import images and drag n drop them to reposition, resize and rotate them. Each object is a widget and the parent of all these objects is a Stack widget. I have used matrix_gesture_detector 0.1.0 library to handle the transformations. I have saved this Stack widget as an image using the screenshot library. However, if the pixelRatio is low, I get pixelated images, but if its high, the image size increases by a lot (around 25MB). I'd like to know how I can improve the quality of the image without increasing the image size. If there are some other approaches I'd like to know about them too. My images can be AssetImage or NetWorkImage.

    My code for taking screenshot:

    ....
    ....
    
    Screenshot(
       controller: screenshotController,
       child: Container(
          key: Key("canvas"),
          decoration: BoxDecoration(
            color: currentColor,
            borderRadius: BorderRadius.all(
              Radius.circular(dp2),
            ),
          ),
          child: Stack(
            alignment: Alignment.center,
            children: _selectedWidgets, // here selected widgets is a lis of widgets
          ),
        ),
      )
    
    //save image method
    saveImage() async {
        
    
        String fileName = DateTime.now().toIso8601String();
        var path = '$directoryPath/$fileName.png';
    
        screenshotController
            .capture(
          pixelRatio: 5,
          path: path,
          delay: Duration(milliseconds: 10),
        ).then((File image) async {
          image = await compressImage(image);
         
          ........
          .........
          
        }).catchError((onError, stack) {
          log("stack = $stack");
        });
      }
    
    // compressing function compress based on the size of the image
    Future<File> compressImage(File image) async {
    
      int fileSize = image.lengthSync();
    
      int percentage = getPercentage(fileSize);
    
      return FlutterNativeImage.compressImage(image.path, quality: 25, percentage: percentage);
    }
    
    int getPercentage(int fileSize) {
      if(fileSize <= 1073741824)
        return 75;
      if(fileSize <= 2147483648)
        return 60;
      if(fileSize <= 3221225472)
        return 50;
      if(fileSize <= 4294967296)
        return 40;
      if(fileSize <= 5368709120)
        return 25;
    
      return 25;
    }