我的情况如下。
我正在从OpenAI的DALLE-2 API中检索一些图像数据。响应以base64编码的JSON形式提供数据。检索后,我将其存储在MongoDB数据库中,作为Schema. Types. Buffer。我正在使用GraphQL的Apollo实现作为我的API查询语言。我需要创建一个自定义的标量类型,这样我就可以为Image模型的 binData 字段分配自定义的标量类型 ImgBinData。请看下面我的类型图片定义:
对于自定义标量类型,我需要在Apollo Server提供的GraphQLScalarType类示例中定义处理逻辑。在这里我创建了Nodejs Buffer并将其保存到图像的 binData 字段。
我不确定我所做的是否正确的地方是,一旦我想检索存储在图像的binData字段中的缓冲区数据。我该怎么做才能把这个二进制数据转换回它所代表的图像?我是否需要更改自定义标量的 serialize 方法中发生的事情?到目前为止,它只是返回Buffer数组中的整数序列:
我想使用此二进制数据作为视图层中图像元素的源值。
@Traynor,这是我的React函数组件代码:
import React from "react";
import { useQuery } from "@apollo/client";
import { GET_IMAGE_BY_ID } from "../utils/queries";
const ProfilePicture = () => {
// run query here
const { loading, error, data } = useQuery(GET_IMAGE_BY_ID, {
variables: { imageId: "64715e7413b66dd4d30eea3b" },
});
if (loading) return null;
if (error) return `Error! ${error}`;
const imgBinData = data?.imageByImageId.binData.data;
console.log(imgBinData);
const imgType = "image/png";
const blob = new Blob([new Uint8Array(imgBinData)], { type: imgType});
const src = URL.createObjectURL(blob);
return (
<img
src={src}
className=""
alt="A headshot of the user"
/>
);
};
export default ProfilePicture;
下面是我的自定义标量逻辑:
const { GraphQLScalarType, Kind } = require("graphql");
const imgBinDataScalar = new GraphQLScalarType({
name: "ImgBinData",
description:
"Custom scalar for storing image bin data in form of Nodejs Buffer type",
serialize: (bufferObj) => bufferObj,
parseValue: (value) => Buffer.from(value, "base64"),
parseLiteral: (ast) => Buffer.from(ast.value, "base64"),
});
module.exports = {
imgBinDataScalar,
};
下面是我从OpenAI的API收到的base64编码的JSON的快照。属性 b64_json 的值是我在上面的自定义标量示例中传递给parseValue方法的值。所有base64编码的字符都被输入Buffer.from方法。我想向你展示这个,这样我就不会在从OpenAI接收数据的那一刻留下任何空白,通过数据转换,直到想要在img元素中显示它。
此外,以下是Chrome DevTools网络选项卡和元素选项卡的快照:
2条答案
按热度按时间z9gpfhce1#
所以,服务器发送buffer为JSON,这意味着你需要将其转换为blob,然后将其转换为URL,这样你就可以将其分配为
img.src
,以便可以显示。因此,将数据数组(我认为是
data.imageByImageId.binData.data
,这就是为什么你应该发布代码,而不是截图)转换为Uint8Array(另外,你需要将图像类型存储到数据库中,并检索它),然后创建一个Blob,然后将Blob转换为URL并将其分配给src属性(你可能需要调整选择器)试试这个:
blmhpbnm2#
看起来你的Scalar实现并没有做你想要的。函数
parseValue
和parseLiteral
采用base64
的String并将其转换为Buffer。我假设您希望在服务器上使用Buffer
类型,并且对于传输层,您希望使用base64
字符串,类似于OpenAI所做的。这些函数可以通过验证和检查来改进,你实际上得到的是字符串,但除此之外,它们看起来很好。同样,假设您希望在服务器上使用
Buffer
类型,并且用于传输层,那么您的serialize
函数是错误的。它返回普通缓冲区。这就是为什么在GraphiQL中,你会得到一个奇怪的对象:让我们修复这个问题,返回一个base64字符串。您可以使用
Buffer
的toString
方法。现在,看起来你在react方面的想法实际上相当不错!您没有添加代码,但浏览器屏幕截图似乎几乎是您想要的(小心,您在
image/jpeg
中有一个错字)。您可以创建使用base64编码数据的源URL。应该就是这里了