如何通过AWS Lambda将MongoDB Atlas中的PNG加载到Unity图像中?

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

How to load a PNG from MongoDB Atlas into a Unity Image via AWS Lambda?

问题

我已将我的PNG图像存储在MongoDB Atlas中作为Buffer。

在将我的服务器迁移到AWS Lambda之前,我曾正确地在后端检索它们:

exports.tree = function(req, res, next) {
    Tree.findOne({ level: parseInt(req.params.level) }, "data", function(err, f) {
        if (err || !f) { res.send(""); return; }
        res.contentType("image/png");
        res.send(f.data);
    });
};

现在我希望将我的后端迁移到AWS Lambda以减少运营成本。

以下是我的当前Lambda函数:

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const { Tree, config } = require('/opt/nodejs/models');
const mongoose = require('mongoose');
mongoose.set('strictQuery', true);
await mongoose.connect(config.DB);

function res(body, type="text/plain"){
   const res = { 
       statusCode: 200,
       isBase64Encoded: false,
       headers: { 
           "Access-Control-Allow-Origin":"*",
           "Content-Type": type 
       },
       multiValueHeader: {},
       body
   };
   return res;
}

export const handler = async(event) => {
   let f = await Tree.findOne({ level: parseInt(event.queryStringParameters.level,10) }, "data");
   if (!f) { return res("");  }
   return res(f.data,"image/png");
};

然而,我无法将它们加载到我的Unity项目中:

...
UnityWebRequest www;
if (l > 30) ll = 30; else ll = l;
if (!T[ll - 1]){
    do  {
            www = UnityWebRequestTexture.GetTexture(Apis.tree+"?level="+ll);
            yield return www.SendWebRequest();
            print(www.downloadedBytes + " Current: " + www.error);
        } while (www.error != null || www.downloadedBytes == 0);
        T[ll - 1] = DownloadHandlerTexture.GetContent(www);
    }
    Tr.GetComponent<Image>().sprite = Sprite.Create(T[ll - 1], new Rect(0f, 0f, T[ll - 1].width, T[ll - 1].height), new Vector2(0.5f, 0.5f), 100f);

它一直显示“内部服务器错误”。

我应该怎么做?

英文:

I have stored my PNG images in MongoDB Atlas as Buffer.

Before I migrated my server to AWS Lambda, I used to retrieve them at the back end correctly:

exports.tree = function(req, res, next) {
    Tree.findOne({ level: parseInt(req.params.level) }, &quot;data&quot;, function(err, f) {
        if (err || !f) { res.send(&quot;&quot;); return; }
        res.contentType(&quot;image/png&quot;);
        res.send(f.data);
    });
};

Now I wish to move my back end to AWS Lambda to cut down my operational costs.

Here is my current Lambda function:

import { createRequire } from &#39;module&#39;;
const require = createRequire(import.meta.url);
const {Tree, config} = require(&#39;/opt/nodejs/models&#39;);
const mongoose = require(&#39;mongoose&#39;);
mongoose.set(&#39;strictQuery&#39;, true);
await mongoose.connect(config.DB);

function res(body, type=&quot;text/plain&quot;){
   const res = { 
       statusCode: 200,
       isBase64Encoded: false,
       headers: { 
           &quot;Access-Control-Allow-Origin&quot;:&quot;*&quot;,
           &quot;Content-Type&quot;: type 
       },
       multiValueHeader: {},
       body
   };
   return res;
}

export const handler = async(event) =&gt; {
   let f = await Tree.findOne({ level: parseInt(event.queryStringParameters.level,10) }, &quot;data&quot;);
   if (!f) { return res(&quot;&quot;);  }
   return res(f.data,&quot;image/png&quot;);
};

However, I couldn't load them into my Unity project:

...
UnityWebRequest www;
if (l &gt; 30) ll = 30; else ll = l;
if (!T[ll - 1]){
	do	{
			www = UnityWebRequestTexture.GetTexture(Apis.tree+&quot;?level=&quot;+ll);
			yield return www.SendWebRequest();
			print(www.downloadedBytes + &quot; Current: &quot; + www.error);
		} while (www.error != null || www.downloadedBytes == 0);
		T[ll - 1] = DownloadHandlerTexture.GetContent(www);
	}
	Tr.GetComponent&lt;Image&gt;().sprite = Sprite.Create(T[ll - 1], new Rect(0f, 0f, T[ll - 1].width, T[ll - 1].height), new Vector2(0.5f, 0.5f), 100f);

It kept saying: "Internal Server Error".

What should I do?

答案1

得分: 0

以下是翻译好的部分:

  1. 我必须使用 REST API 而不仅仅是 HTTP API,并允许图像/png二进制格式。

  2. 我必须从响应中删除 multiValueHeader: {}。

  3. 我必须在返回响应主体之前将缓冲区转换为 base64 字符串。

  4. 对于 Unity 部分,这是我的代码:

do {
    www = UnityWebRequest.Get(Apis.tree + "?level=" + ll);
    yield return www.SendWebRequest();
    print(www.downloadedBytes + " Current: " + www.error);
} while (www.error != null || www.downloadedBytes == 0);

byte[] imageBytes = Convert.FromBase64String(www.downloadHandler.text);
T[ll - 1] = new Texture2D(2048, 2048, TextureFormat.ARGB32, false);
T[ll - 1].LoadImage(imageBytes);
Tr.GetComponent<Image>().sprite = Sprite.Create(T[ll - 1], new Rect(0.0f, 0.0f, T[ll - 1].width, T[ll - 1].height), new Vector2(0.5f, 0.5f), 100.0f);
英文:

A few changes were needed:

  1. I had to use the REST API and not just the HTTP API, and allow the image/png binary format.

  2. I had to remove multiValueHeader: {} from the response.

  3. I had to convert the buffer to a base64 string before returning it in the response body.

  4. For the Unity part, here is my code:

     	do{
     		www = UnityWebRequest.Get(Apis.tree+&quot;?level=&quot;+ll);
     		yield return www.SendWebRequest();
     		print(www.downloadedBytes + &quot; Current: &quot; + www.error);
     	} while (www.error != null || www.downloadedBytes == 0);
     	byte[] imageBytes = Convert.FromBase64String(www.downloadHandler.text);
     	T[ll - 1] = new Texture2D(2048, 2048, TextureFormat.ARGB32, false);
     	T[ll - 1].LoadImage(imageBytes);
      	Tr.GetComponent&lt;Image&gt;().sprite = Sprite.Create(T[ll - 1], new Rect(0.0f, 0.0f, T[ll - 1].width, T[ll - 1].height), new Vector2(0.5f, 0.5f), 100.0f);
    

huangapple
  • 本文由 发表于 2023年1月8日 13:49:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75045769.html
匿名

发表评论

匿名网友

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

确定