How can I read (from disk) and resize an image, in Flutter/Dart

前端 未结 8 642
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-09 08:53

In Flutter/Dart, how can I perform the following 3 steps:

  1. Read an image from disk,
  2. Read its original dimensions (width and height),
  3. Resiz
相关标签:
8条回答
  • 2020-12-09 08:58

    You can read image from the disk using the image.file constructor.

    For more features you can use the Image library

    A Dart library providing the ability to load, save and manipulate images in a variety of different file formats.

    Sample from the documentation examples

    Load a jpeg, resize it and save it as a png

        import 'dart:io' as Io;
        import 'package:image/image.dart';
        void main() {
          // Read a jpeg image from file.
          Image image = decodeImage(new Io.File('test.jpg').readAsBytesSync());
    
          // Resize the image to a 120x? thumbnail (maintaining the aspect ratio).
          Image thumbnail = copyResize(image, width: 120);
    
          // Save the thumbnail as a PNG.
          new Io.File('out/thumbnail-test.png')
                ..writeAsBytesSync(encodePng(thumbnail));
        }
    
    0 讨论(0)
  • 2020-12-09 09:00

    You can use the dart image package: https://pub.dartlang.org/packages/image.

    The package provide various services such as resize, crop and rotate.

    While this package does work, unfortunately it is very slow.

    See discussion: https://github.com/brendan-duncan/image/issues/55

    0 讨论(0)
  • 2020-12-09 09:02

    To resize an image that is defined in pubspec.yaml use "BoxFit":

    @override
    Widget build(BuildContext context) {
      return (new Container(
        width: 250.0,
        height: 250.0,
          alignment: Alignment.center,
          decoration: new BoxDecoration(
    
          image: DecorationImage(
              image: AssetImage('assets/Launcher_Icon.png'),
              fit: BoxFit.fill
          ),
        ),
      ));
    }
    

    also reference how to access images: https://flutter.io/assets-and-images/

    0 讨论(0)
  • 2020-12-09 09:04

    Use the ResizeImage image provider.

    Using a separate package is nice if you want to use many of the functionality, or if you can't do otherwise. But just to depend on something instead of what the framework itself (and its underlying graphics engine) can do easily... :-)

    If you have an ImageProvider now, say, to display an image from the bytes in memory:

    Image(image: MemoryImage(bytes))
    

    Just wrap it inside a ResizeImage:

    Image(image: ResizeImage(MemoryImage(bytes), width: 50, height: 100))
    

    And if you want even more control, just create your own image provider based on the source code of this one.

    0 讨论(0)
  • 2020-12-09 09:05

    It's not a very good way to resize picture via Image library, since it blocks ui thread, and it brings very bad UX. There is a a maxWidth argument in image_picker lib, you can set it, so these writing files manipulation will be unnecessary in some cases.

    0 讨论(0)
  • 2020-12-09 09:13

    Here's an example Thumbnail widget which does this on the flight

    It uses Isolate to offload CPU-intensive work to background thread and have UI thread jank-free

    import 'dart:io';
    import 'dart:isolate';
    import 'package:flutter/material.dart';
    import 'package:image/image.dart' as IMG;
    import 'package:path/path.dart';
    
    class Thumbnail extends StatefulWidget {
      final Size size;
      final File image;
    
      const Thumbnail({Key key, this.size, this.image}) : super(key: key);
      @override
      _ThumbnailState createState() => _ThumbnailState();
    }
    
    class _ThumbnailState extends State<Thumbnail> {
      List<int> imgBytes;
      Isolate isolate;
    
      @override
      void initState() {
        _asyncInit();
    
        super.initState();
      }
    
      static _isolateEntry(dynamic d) async {
        final ReceivePort receivePort = ReceivePort();
        d.send(receivePort.sendPort);
    
        final config = await receivePort.first;
    
        print(config);
    
        final file = File(config['path']);
        final bytes = await file.readAsBytes();
    
        IMG.Image image = IMG.decodeImage(bytes);
        IMG.Image thumbnail = IMG.copyResize(
          image,
          width: config['size'].width.toInt(),
        );
    
        d.send(IMG.encodeNamedImage(thumbnail, basename(config['path'])));
      }
    
      _asyncInit() async {
        final ReceivePort receivePort = ReceivePort();
        isolate = await Isolate.spawn(_isolateEntry, receivePort.sendPort);
    
        receivePort.listen((dynamic data) {
          if (data is SendPort) {
            if (mounted) {
              data.send({
                'path': widget.image.path,
                'size': widget.size,
              });
            }
          } else {
            if (mounted) {
              setState(() {
                imgBytes = data;
              });
            }
          }
        });
      }
    
      @override
      void dispose() {
        if (isolate != null) {
          isolate.kill();
        }
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          height: widget.size.height,
          width: widget.size.width,
          child: imgBytes != null
              ? Image.memory(
                  imgBytes,
                  fit: BoxFit.cover,
                )
              : Container(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      colors: [Colors.grey[100], Colors.grey[300]],
                      begin: Alignment.centerLeft,
                      end: Alignment.centerRight,
                    ),
                  ),
                ),
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题