【问题标题】:How to load images with image.file如何使用 image.file 加载图像
【发布时间】:2018-04-14 19:58:53
【问题描述】:

我似乎无法简单地将图像从硬盘加载到屏幕上。 Image.network 看起来很简单。但我不知道如何使用 Image 或 Image.file。图像似乎需要一个流,所以我认为这不是我想要的。

import 'package:flutter/material.dart';
import 'dart:io';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
    File file = new File("Someimage.jpeg");
    @override
    Widget build(BuildContext context) {
        return new MaterialApp(
            home: new Image.file(file),  //doesn't work, but no errors
        );
    }
}

我将 Someimage 添加到 pubspec.yaml 文件中,但这也不起作用:

assets:
    - Someimage.jpeg

谁能给我一个例子来说明这是如何做到的?谢谢。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    ImageImageProvider的区别和关系:

    Image:

    创建一个显示图像的小部件。

    要显示来自网络或资产包的图像,请考虑分别使用 [new Image.network] 和 [new Image.asset]。

    所以Image 是一个小部件。就像 html 中的 <img> 标签一样。

    ImageProvider:

    在不提交精确的最终资产的情况下识别图像。这允许识别一组图像,并在以后根据环境解析精确的图像,例如。设备像素比。

    所以ImageProvider 就像Imagesrc 属性。

    现在Image 接受一个参数image,它是一个ImageProvider。 有 4 种方式获取ImageProvider

    • AssetImage:

      用于加载与 apk 一起打包的预定义图像集。

      例如要显示横幅图像,需要一些自定义图标。

    • NetworkImage:

      用于从互联网加载动态图片。

    • FileImage:

      用于从目标设备中的文件系统加载图像。

      例如显示新下载的图像。

    • MemoryImage:

      用于从内存中加载原始图像。

      例如获取用户的壁纸并将其加载到小部件中。

    现在他们都是ImageProviders。 它们中的任何一个都可以用作Image 小部件的image 属性。 Flutter 社区通过向 Image 小部件本身添加扩展类来简化语法。

    所以

    • Image.asset(name) 本质上是Image(image: AssetImage(name))
    • Image.file(path) 本质上是Image(image: FileImage(File(path)))
    • Image.network(url) 本质上是Image(image: NetworkImage(url))
    • Image.memory(list) 本质上是 Image(image: MemoryImage(list))

    现在应该很清楚了

    • apk 大小随着资产图片的数量而增加。

    • 他们的加载时间(用户看到的)通常是按顺序排列的

      NetworkImage > FileImage > AssetImage > MemoryImage

    【讨论】:

    • 您在引用时应确保对includeyour 的引用
    • 有没有办法从 FadeInImage.assetNetwork OR ImageProvider (FadeInImage.assetNetwork.image return ImageProvider) 获取图像并保存到文件?
    【解决方案2】:

    这是一个使用 Image.file 的例子。这不是推荐的方式,但用例可能是您通过 http 在应用中下载了图像,然后想要显示该图像(例如,图像在安装过程中未存储在资产中)。

    在您的 pubspec.yaml 中,添加:

    path_provider: ^0.2.2
    

    代码:

    import 'dart:io';
    import 'dart:async';
    import 'package:path_provider/path_provider.dart';
    import 'package:flutter/material.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
    
      Future<File> _getLocalFile(String filename) async {
        String dir = (await getApplicationDocumentsDirectory()).path;
        File f = new File('$dir/$filename');
        return f;
      }
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
            title: 'Flutter Demo',
            home: new FutureBuilder(
                future: _getLocalFile("flutter_assets/image.png"),
                builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
                  return snapshot.data != null ? new Image.file(snapshot.data) : new Container();
                })
        );
      }
    }
    

    要模拟下载图像,您可以使用 adb 推送图像:

    adb push image.png /data/data/com.example.imagetest/app_flutter/flutter_assets/
    

    【讨论】:

      【解决方案3】:

      这是另一个使用 jpg 作为背景图像的示例。它还会对图像应用不透明度。

      import 'package:flutter/material.dart';
      
      void main() => runApp(new MyApp());
      
      class MyApp extends StatelessWidget {
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
          return new MaterialApp(
            title: 'Flutter Demo',
            theme: new ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: new Scaffold(
              resizeToAvoidBottomPadding: false,
              appBar: new AppBar(
                title: new Text("test"),
              ),
              body: new Container(
                decoration: new BoxDecoration(
                  image: new DecorationImage(
                    colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.6), BlendMode.dstATop),
                    image: new AssetImage("assets/images/keyboard.jpg"),
                    fit: BoxFit.cover,
                  ),
                ),
              ),
            ),
          );
        }
      }
      

      【讨论】:

      • 这绝对回答了我关于如何显示图像的问题,但是图像显示可以用 image.file 完成吗?我找不到image.file的任何用途,所以我不知道它为什么存在。
      【解决方案4】:

      试试这个:

      import 'package:flutter/material.dart';
      import 'dart:io';
      
      void main() => runApp(new MyApp());
      
      class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
              return new MaterialApp(
                      home: new ImageIcon(
                                new AssetImage(
                                    "assets/images/image.png"),
                                size: 24.0,
                                color: Colors.white),
              );
          }
      }
      

      在 pubspec.yaml 中,你需要:

        assets:
          - assets/images/image.png
      

      【讨论】:

      • 谢谢。这段代码也不适合我。我所看到的只是一个空白的白色盒子,而不是图像。我删除了颜色属性,但我得到的只是一个黑盒子。
      • 您的运行窗口是否有任何错误?如果找不到资产,您将在运行时收到错误消息:“无法加载资产”
      • 这很有趣。我正在使用 IntelliJ,我完全没有错误。我查看了图像、图像位置、名称以及所有内容。还有其他想法吗?对不起。
      • 这有效,但它似乎只是有效,因为它是该图像的一种颜色。有没有办法获得全彩色图像来渲染?而且 image.file 是没用的方法吗?
      【解决方案5】:
      child: Image.file(
       File('DirectoryLocation/imageName.jpg'),
       height: 45.0,
       width: 45.0,
      ),
      

      【讨论】:

        【解决方案6】:

        您可以将Image.File 添加为Container 的孩子

        Container(
             padding:
                EdgeInsets.zero,
                 height: 150,
                       width: 150,
                       child: Image.file(File(filePath))
           )
        

        【讨论】:

        • 我认为如果您能提及file 变量应该包含的内容,这对初学者会更有帮助。就像“位于用户设备中的图像文件的路径”。
        【解决方案7】:

        替换

        new Image.file(file)
        

        FileImage(file)
        

        这应该适合你。

        【讨论】:

          【解决方案8】:

          如果您的图片在资产中,您可以使用image.asset 构造函数

          【讨论】:

          • 你能告诉我这是如何工作的吗? new Image.asset(file) 不起作用。 new Image.asset("images/Someimage.jpeg") 不起作用。我真的在努力,但我显然缺少一些基本的东西。
          【解决方案9】:

          Flutter 在pubspec.yaml 中包含断言部分,其中包含应用程序的断言。 例如:

          assets:
              - data_repo/img/ic_launcher.png
          

          1.使用 pubspec.yaml:

          import 'package:flutter/material.dart';
          
          void main() {
            runApp(new MaterialApp(home: LoadLocalImage()));
          }
          
          class LoadLocalImage extends StatelessWidget {
            @override
            Widget build(BuildContext context) {
              return new Scaffold(
                appBar: new AppBar(
                  title: new Text("Load Local Image"),
                ),
                body: new Container(
                  decoration: new BoxDecoration(
                      image: new DecorationImage(
                          image: new AssetImage('data_repo/img/ic_launcher.png'), fit: BoxFit.cover)),
                ),
              );
            }
          }
          

          2。使用 Image.asset:

          import 'package:flutter/material.dart';
          
              void main() {
                runApp(new MaterialApp(home: LoadLocalImage()));
              }
          
              class LoadLocalImage extends StatelessWidget {
                @override
                Widget build(BuildContext context) {
                  return new Scaffold(
                      appBar: new AppBar(
                        title: new Text("Load Local Image"),
                      ),
                      body: Image.asset(
                        'data_repo/img/ic_launcher.png',
                        fit: BoxFit.cover,
                      ));
                }
              }
          

          文件夹结构: 输出:

          更多描述请参考以下链接:

          https://flutter.dev/docs/cookbook/images/network-image

          【讨论】:

            【解决方案10】:

            首先使用这个包:

            import 'package:http/http.dart' show get;
            import 'dart:io';
            
            Image loadImageFromFile(String path) {
                File file = new File(path);
                Image img = Image.file(file);
            }
            
            void storeImageToFile(String path,String url) async {
                var response = await get(Url);
                File file = new File(path);
                file.create(recursive: true).then((val) async {
                    if (await val.exists()) {
                        await file.writeAsBytesSync(response.bodyBytes);
                    }
                });
            }
            

            【讨论】:

              【解决方案11】:

              pubspec.yaml 中的资产必须取消注释。
              这将有助于按预期加载文件 image.asset。

              【讨论】:

                【解决方案12】:

                可能帮助您寻找更多内容来解决与从存储中加载文件(即 Someimage.jpeg )相关的问题。让我解释一下。

                首先你应该知道一些重要的点。

                1. 在 Flutter 中,Folder 被称为 Directory。
                2. 内置存储本身就是一个目录,其路径为'/storage/emulated/0/',可以使用Directory('/storage/emulated/0/')访问强>
                3. 类似的下载文件夹路径是'/storage/emulated/0/Download/',可以使用Directory('/storage/emulated/0/Download/')访问强>
                4. Download文件夹中的图片路径可以是'/storage/emulated/0/Download/Someimage.jpeg'
                5. Camera 文件夹中的图像路径可以是 '/storage/emulated/0/DCIM/Camera/Someimage.jpeg' ,等

                如果您对查找路径有任何问题,那么只需打开文件管理器并检查文件(图片)detail,您会在其中找到.

                示例:-

                Align(
                alignment: Alignment.topCenter,
                child: Image.file(
                File('/storage/emulated/0/DCIM/Camera/Someimage.jpeg'),
                fit: BoxFit.contain,
                ),
                ),
                

                确保您拥有存储访问权限。

                【讨论】:

                  猜你喜欢
                  • 2021-05-30
                  • 2021-11-24
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-03-12
                  • 2018-06-13
                  • 2021-04-09
                  相关资源
                  最近更新 更多