【问题标题】:Problems loading images from bytes in Flutter/Dart在 Flutter/Dart 中从字节加载图像的问题
【发布时间】:2020-01-08 10:00:24
【问题描述】:

我正在使用 Flutter 构建一个应用程序。我正在使用多种我正在努力拼凑起来的新技术。

我的实际问题是使用以下方法时无法在应用中加载图像:

  1. 使用 Mongoengine 将测试数据插入 MongoDB,使用 this method 将图像插入 GridFS。
  2. 查询 GraphQL 服务器以获取数据和检索数据,并以 bytes 的形式从 GridFS 接收图像,但采用 string - 例如“b'/9j/4AAQSkZJRgABAQEASABIAAD/4V0X ....'”
  3. 使用该字节字符串在应用程序中加载图像,例如Image.memory()

但图片无法加载并出现错误:type String is not a subtype of type Uint8List。所以我尝试通过执行以下操作将字节字符串从 String 转换为原始字节:

List<int> bytesList = imageData['image']['data'].codeUnits;
Uint8List thumbImageBytes = Uint8List.fromList(bytesList);

我得到以下异常:

I/flutter ( 4303): ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞══════
I/flutter ( 4303): The following _Exception was thrown while resolving an image:
I/flutter ( 4303): Exception: Could not instantiate image codec.

我不知道我能做些什么来解决这个问题,我似乎无法通过谷歌搜索等找到任何东西。除了this S.O question 这是我试图做的事情之外,似乎没有可用于此确切情况的信息.我还尝试了 cmets 中建议的所有方法,按照建议的链接并尝试了所有可用的答案组合、cmets 以及所有内容。

我的设置如下;

主应用:Flutter/Dart
API 服务器:基于 Python/Flask/Mongoengine 的 GraphQL/Graphene API 后端数据库:MongoDB

Python 方面;

Mongoengine 文档模型:

class Product(Document):
    meta = {'collection': 'product'}
    name = StringField(unique=True)
    price = FloatField()
    sale_price = FloatField()
    description = StringField()
    image = FileField()
    thumb = FileField()
    created_at = DateTimeField(default=datetime.utcnow)
    edited_at = DateTimeField()
    # user = ReferenceField(User)

    def __repr__(self):
        return f'<Product Model::name: {self.name}>'

模型的石墨烯模式:

class ProductAttribute:
    name = graphene.String()
    price = graphene.Float()
    sale_price = graphene.Float()
    description = graphene.String()
    image = Upload()
    thumb = graphene.String()
    created_at = graphene.DateTime()
    edited_at = graphene.DateTime()

class Product(MongoengineObjectType):
    """Product node."""

    class Meta:
        model = ProductModel
        interfaces = (graphene.relay.Node,)

class CreateProductInput(graphene.InputObjectType, ProductAttribute):
    """Arguments to create a product."""
    pass

class CreateProduct(graphene.Mutation):
    """Create a product."""
    product = graphene.Field(lambda: Product, description="Product created by this mutation.")

    class Arguments:
        input = CreateProductInput()
        image = Upload(required=True)

    def mutate(self, info, image, input):
        data = utils.input_to_dictionary(input)
        data['created_at'] = datetime.utcnow()
        data['edited_at'] = datetime.utcnow()
        print(data)

        product = ProductModel(**data)
        product.save()

        return CreateProduct(product=product)

我的基本石墨烯架构:

class Query(graphene.ObjectType):
    """Query objects for GraphQL API."""

    node = graphene.relay.Node.Field()
    single_product = graphene.relay.Node.Field(schema_product.Product)
    all_products = MongoengineConnectionField(schema_product.Product)

class Mutations(graphene.ObjectType):
    createProduct = schema_product.CreateProduct.Field()


schema = graphene.Schema(query=Query, types=[schema_product.Product], mutation=Mutations)

【问题讨论】:

  • 您确定您的图像没有使用 base64 编码为字符串吗?如果您得到的字符串完全由可打印字符组成,这似乎相当可疑。

标签: python-3.x mongodb flutter dart graphql


【解决方案1】:

这是非常可疑的:

  1. 您的二进制数据存储在String 中(这通常是错误的)。
  2. 您的String 恰好完全由可打印字符组成。

因此,您可能会将已编码 的二进制数据返回为可打印的字符串。一种常见的编码是 base64,果然,当我尝试对几种不同类型的图像进行 base64 编码时,我看到 base64 编码的 JPEG 文件会生成一个以/9j/4AAQSk 开头的字符串,就像你得到的字符串一样。

您肯定会返回 base64 编码的数据。如果您不自己进行编码,那么某些东西会自动为您进行编码,并且可能有一种对称机制可以为您解码。如果没有,您需要显式地对您的String 进行base64 解码以取回二进制数据。您可以使用dart:convert 为您解码。

【讨论】:

  • 嘿,谢谢,我应该意识到它实际上是base64!所以基本上字节来自pythonopen(file, 'rb'),它给出了b'&lt;STRING&gt;'字节表示,然后用mongodb就可以了,但是当石墨烯将数据传回时,它是一个像"b'&lt;STRING&gt;'"这样的字符串,所以字节表示变成了一个字符串。我只是将字符串“切片”String byteString = allProductsItem['thumb']['data']; Uint8List thumbImage = base64.decode(byteString.substring(2, byteString.length - 1));
猜你喜欢
  • 2020-05-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-16
相关资源
最近更新 更多