dart flutter中如何将图像存储到缓存的网络图像中

xkrw2x1b  于 2023-01-22  发布在  Flutter
关注(0)|答案(7)|浏览(141)

我有下面的代码,我从firebase存储中获取一个图像作为一个图像。现在,我想把这个图像存储在我的CachedNetworkImage中,这样我就不必每次都从DB中获取它。由于cachednetworkimage需要一个URL,而我正在获取一个图像,我如何使用cachednetworkimage?
这是我的代码

final FirebaseStorage storage = FirebaseStorage(
      app: Firestore.instance.app,
      storageBucket: 'gs://my-project.appspot.com');

  Uint8List imageBytes;
  String errorMsg;

  _MyHomePageState() {
      storage.ref().child('selfies/me2.jpg').getData(10000000).then((data) =>
                setState(() {
                  imageBytes = data;
                })
        ).catchError((e) =>
                setState(() {
                  errorMsg = e.error;
                })
        );
  }

  @override
  Widget build(BuildContext context) {
    var img = imageBytes != null ? Image.memory(
        imageBytes,
        fit: BoxFit.cover,
      ) : Text(errorMsg != null ? errorMsg : "Loading...");

    return new Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
        ),
        body: new ListView(
          children: <Widget>[
            img,
          ],
        ));
  }
}```
azpvetkf

azpvetkf1#

缓存的网络图像和Flutter缓存管理器

Cached network image包依赖于另一个名为Flutter缓存管理器的包来存储和检索图像文件。
∮ ∮ ∮ ∮
你需要下载你的图像文件,并使用软件包将它们放入缓存。下面是一个示例代码,它从Firebase存储中获取文件及其下载URL,并将它们放入缓存:

// import the flutter_cache_manager package
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
// ... other imports

class MyCacheManager {
  Future<void> cacheImage() async {
    final FirebaseStorage storage = FirebaseStorage(
      app: Firestore.instance.app,
      storageBucket: 'gs://my-project.appspot.com',
    );

    final Reference ref = storage.ref().child('selfies/me2.jpg');
    
    // Get your image url
    final imageUrl = await ref.getDownloadURL();

    // Download your image data
    final imageBytes = await ref.getData(10000000);

    // Put the image file in the cache
    await DefaultCacheManager().putFile(
      imageUrl,
      imageBytes,
      fileExtension: "jpg",
    );
  }
}

∮ ∮ ∮ ∮
接下来,您将使用CacheNetworkImage小部件,如documentation中所示。

// ... some code

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: CachedNetworkImage(
      imageUrl: "your_image_link_here",
      placeholder: (context, url) => CircularProgressIndicator(),
      errorWidget: (context, url, error) => Icon(Icons.error),
    ),
  );
}

如果您使用Flutter缓存管理器将图像文件放入缓存中,缓存网络图像将直接从缓存中检索它们。如果您的图像文件过期或缓存被清除,它将下载并将它们放入缓存中。

完整示例

import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';

class MyCacheManager {
  final _storage = FirebaseStorage(
    app: FirebaseFirestore.instance.app,
    storageBucket: 'gs://my-project.appspot.com',
  );

  final defaultCacheManager = DefaultCacheManager();

  Future<String> cacheImage(String imagePath) async {
    final Reference ref = _storage.ref().child(imagePath);

    // Get your image url
    final imageUrl = await ref.getDownloadURL();

    // Check if the image file is not in the cache
    if ((await defaultCacheManager.getFileFromCache(imageUrl))?.file == null) {
      // Download your image data
      final imageBytes = await ref.getData(10000000);

      // Put the image file in the cache
      await defaultCacheManager.putFile(
        imageUrl,
        imageBytes,
        fileExtension: "jpg",
      );
    }

    // Return image download url
    return imageUrl;
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _imageUrl;

  @override
  void initState() {
    final myCacheManager = MyCacheManager();

    // Image path from Firebase Storage
    var imagePath = 'selfies/me2.jpg';
    
    // This will try to find image in the cache first
    // If it can't find anything, it will download it from Firabase storage
    myCacheManager.cacheImage(imagePath).then((String imageUrl) {
      setState(() {
        // Get image url
        _imageUrl = imageUrl;
      });
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _imageUrl != null
            ? CachedNetworkImage(
                imageUrl: _imageUrl,
                placeholder: (context, url) => CircularProgressIndicator(),
                errorWidget: (context, url, error) => Icon(Icons.error),
              )
            : CircularProgressIndicator(),
      ),
    );
  }
}
e5nqia27

e5nqia272#

尝试使用firebase_image package. From here的方法,您需要同步图像URL(selfies/me2.jpg)和桶URL(gs:my-project.appspot.com)

Image(
        image: FirebaseImage('gs://bucket123/userIcon123.jpg'),
        // Works with standard parameters, e.g.
        fit: BoxFit.fitWidth,
        width: 100,
        // ... etc.
      )
sshcrbum

sshcrbum3#

我不是消防站的用户,但这应该工作。
它可能需要一点修改或东西,请在评论中分享更新我的答案根据这一点
您可以按如下方式获取文件对象。

import 'dart:io';
import 'dart:typed_data';

Uint8List readyData = imageBytes;
File('my_image.jpg').writeAsBytes(bodyBytes);

并使用image_gallery_saver保存它,因此代码应如下所示

Future<String> _createFileFromString() async {
  final encodedStr = "...";
  Uint8List bytes = base64.decode(imageBytes);
  String dir = (await getApplicationDocumentsDirectory()).path;
  String fullPath = '$dir/abc.png';
  print("local file full path ${fullPath}");
  File file = File(fullPath);
  await file.writeAsBytes(bytes);
  print(file.path);

  final result = await ImageGallerySaver.saveImage(bytes);
  print(result);

  return file.path;
}
falq053o

falq053o4#

对于您的存储示例,请使用如下方法

Future<void> downloadURLExample() async {
      String downloadURL = await storage.ref('selfies/me2.jpg')
          .getDownloadURL();

  // Within your widgets:
  // CachedNetworkImage(imageUrl: downloadURL);
}
of1yzvn4

of1yzvn45#

为了让它与Firebase存储一起工作,并包含离线功能,我对它进行了这样的更改

Future<String> cacheImage(String imagePath) async {
    
   var fileinfo = await defaultCacheManager.getFileFromCache(imagePath);
   if(fileinfo != null)
   {
     return fileinfo.file.path;
   } else{

      final Reference ref = _storage.child(imagePath);

      // Get your image url
      final imageUrl = await ref.getDownloadURL();

      // Check if the image file is not in the cache
      
        // Download your image data
        final imageBytes = await ref.getData(10000000);

        // Put the image file in the cache
      var file = await defaultCacheManager.putFile(
          imageUrl,
          imageBytes!,
          key: imagePath,);
        

        return file.path;
   }

    }
hs1ihplo

hs1ihplo6#

对于任何人仍然坚持这一点..尝试这不需要黑客和使用CachedNetworkImageProvider内置的检索方法。
第一屏:

CachedNetworkImage(
imageUrl: "https://whereismyimage.com",
 progressIndicatorBuilder:
(context, url, progress) {
 return CircularProgressIndicator(
value: progress.progress,
 );
},
errorWidget: (context, url, error) => const Icon(Icons.error),
),

然后第二个屏幕

Image(image: CachedNetworkImageProvider("https://whereismyimage.com)"),

CachedNetworkImageProvider知道如何使用URL检索缓存的图像。

23c0lvtd

23c0lvtd7#

查看cached_network_image: ^2.5.0软件包。
如何使用它?

CachedNetworkImage(
        imageUrl: "http://via.placeholder.com/350x150",
        placeholder: (context, url) => CircularProgressIndicator(),
        errorWidget: (context, url, error) => Icon(Icons.error),
     ),

相关问题