在同一个网格视图中显示数据库图像选择和资产文件的最佳实践

huangapple go评论58阅读模式
英文:

Best practice for showing db imagepicked and asset files in the same GridView

问题

我想了解如何以最佳方式显示来自资产和图像选择图像(存储在数据库中)的图片以展示在同一个网格视图中。我使用了一个 Photo 模型类,其中有不同的变量来存储这些图像,assetPath 用于存储资产图像,fileName 用于存储来自数据库的图像(这些通过实用方法转换为 Image.memory)。问题在于我将图像存储在同一个列表中以便显示,但当一些图像是 base64 编码,而另一些是 assetPath(字符串)时,就会出现问题。关于这点有什么最佳做法?

这是我的测试代码。我在这里尝试检查照片是否包含 assetPath,如果包含,它就是资产图像,否则它是图像选择的图像,然后我使用实用方法将其显示为 Image.memory

在实际设备上测试应用程序时,资产图像显示正常,但数据库(图像选择)文件只是空白的方块(这可能是因为是 base64 编码)。

我还可以提到图像选择和数据库实用方法运行良好,所以我选择不在此处包含它们。主要问题如前所述是如何最佳地在同一个网格视图中显示来自资产和数据库的图像选择文件。

网格视图:

gridview2() {
    // ... 其他代码 ...

    return Padding(
        padding: const EdgeInsets.all(5.0),
        child: GridView.builder(
            itemCount: images!.length,
            gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                maxCrossAxisExtent: 200,
                crossAxisSpacing: 20,
                mainAxisSpacing: 20),
            itemBuilder: (BuildContext ctx, int index) {
                return Container(
                    decoration: BoxDecoration(
                        image: DecorationImage(
                            fit: BoxFit.cover,
                            //todo we need a check if String is database base64 or asset path??
                            image: images![index].fileName!.isNotEmpty
                                ? Image.asset(images![index].fileName!).image
                                : Utility.imageFromBase64String(images![index].fileName!).image),
                    ),
                );
            },
        ),
    );
}

Scaffold: 
// ... 其他代码 ...

initState 函数: 
// ... 其他代码 ...

refreshImages 函数: 
// ... 其他代码 ...

 Gridview2 函数中我使用的解决方案:
return Container(
    decoration: BoxDecoration(
        image: DecorationImage(
            fit: BoxFit.cover,
            image: images![index].assetPath != null
                ? Image.asset(images![index].assetPath!).image
                : Utility.imageFromBase64String(images![index].fileName!).image,
        ),
    ),
);
英文:

I would like to have some insight into what is the best way to go to show images from assets and imagePicked images (stored in db) in the same gridView? I am using a Photo model class with different variables to store the images, assetPath to store assetimages and fileName to store images from db (these are converted to Image.memory through a utillity method). The problem as I see it is that i Store the images in the same List to be able to display them but this raises issues when some images are base64 and others are assetPath (String). whats best practice regarding this?

Here is my test code. I am here trying to check if the photo contains an assetPath and if so its an asset image otherwise its an imagepicked image and then I use utility method and display it as an Image.memory.

When I test the app on a physical device it shows the asset images fine but the database (imagepicked ) files are just empty squares (as it should be because of base64 I suppose).

I can also mention that the imagepicking and database utility methods are working fine so I choose to not include them here. The main issue is as mentioned best practice for showing both asset and imagepicked from database files in the same gridview.

gridView:

gridview2() {
    
    String image1 = ('images/lake.jpg');
    String image2 = ('images/flower1.png');

    Photo photo1 = Photo(id: 0, fileName: image1);
    Photo photo2 = Photo(id: 0, fileName: image2);

    images!.add(photo1);
    images!.add(photo2);

    return Padding(
        padding: const EdgeInsets.all(5.0),
        child: GridView.builder(
            itemCount: images!.length,
            gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                maxCrossAxisExtent: 200,
                crossAxisSpacing: 20,
                mainAxisSpacing: 20),
            itemBuilder: (BuildContext ctx, int index) {
              return Container(
                  decoration: BoxDecoration(
                image: DecorationImage(
                    fit: BoxFit.cover,
                    
                    //todo we need a check if String is database base64 or asset path??
                    image: images![index].fileName!.isNotEmpty
                        ? Image.asset(images![index].fileName!).image
                        : Utility.imageFromBase64String(
                                images![index].fileName!)
                            .image),
              ));
            }));
  }   

Scaffold:

@override
  Widget build(BuildContext context) {
    

    return Scaffold(
      appBar: AppBar(
        title: const Center(child: Text('ImagePicker Database test')),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.add),
            onPressed: () {
              setState(() {
          
                pickImagesFromGallery();
              });
            },
          ),
        ],
      ),
      body: Column(
        children: <Widget>[
          Flexible(child: gridview2()),
        ],
      ),
    );
  }
}

initState function:

void initState() {
    
    super.initState();
    images = [];
    dbHelper = DBHelper();
    
    refreshImages();
    
  }

RefreshImage function:

refreshImages() {
    
    dbHelper!.getPhotos().then((imgs) {
      setState(() {
        //Clears list
        images!.clear();
        //Add all images from imgs (database) to images list
        images!.addAll(imgs);
      });
    });
  }

Solution I used in the Gridview2 function:

return Container(
                  decoration: BoxDecoration(
                image: DecorationImage(
                    fit: BoxFit.cover,
                    
                    image: images![index].assetPath != null
                        ? Image.asset(images![index].assetPath!).image
                        : Utility.imageFromBase64String(
                                images![index].fileName!)
                            .image),
              ));

From physical phone when loaded and added one picked file (becomes empty):

在同一个网格视图中显示数据库图像选择和资产文件的最佳实践

答案1

得分: 1

我会调整你的照片模型,使其具有 assetPath 和 base64String 两个单独的字段。这样你就可以确切知道图像数据的样子。

DecorationImage(
    fit: BoxFit.cover,
    image: images![index].fileName!.isNotEmpty
        ? Image.asset(images![index].fileName!).image
        : Utility.imageFromBase64String(
                images![index].byteString!) // THIS
            .image),
)

我也会仔细检查你的 Utility.imageFromBase64String() 函数,确保它能够单独正常运行。

英文:

I would adjust your Photo model to have separate fields for assetPath and base64String. This way you can know for sure what the image data looks like.

DecorationImage(
                    fit: BoxFit.cover,
                    image: images![index].fileName!.isNotEmpty
                        ? Image.asset(images![index].fileName!).image
                        : Utility.imageFromBase64String(
                                images![index].byteString!) // THIS
                            .image),
              )

I would also double check your Utility.imageFromBase64String() function to make sure that works by itself.

答案2

得分: 0

有一个单独的字段用于图像资产,并对空值进行检查,而不是使用 "isNotEmpty" 检查,似乎解决了问题。我不确定这是否是一个好的解决方案,可能不是,但它有效!我会编辑代码以反映可运行的代码。感谢 Banjoe 提出单独字段的建议!

英文:

To have a separate field for the imageAsset and also do a check for nulls instead of "isNotEmpty" check seems to have fixed the issue. I have no idéa though if this is a good solution, probably not but it works! I will edit the code to reflect the working code. Thank you Banjoe for the suggestion with separate fields!

huangapple
  • 本文由 发表于 2023年2月19日 21:58:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500636.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定