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

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

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

问题

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

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

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

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

以下是我的当前Lambda函数:

  1. import { createRequire } from 'module';
  2. const require = createRequire(import.meta.url);
  3. const { Tree, config } = require('/opt/nodejs/models');
  4. const mongoose = require('mongoose');
  5. mongoose.set('strictQuery', true);
  6. await mongoose.connect(config.DB);
  7. function res(body, type="text/plain"){
  8. const res = {
  9. statusCode: 200,
  10. isBase64Encoded: false,
  11. headers: {
  12. "Access-Control-Allow-Origin":"*",
  13. "Content-Type": type
  14. },
  15. multiValueHeader: {},
  16. body
  17. };
  18. return res;
  19. }
  20. export const handler = async(event) => {
  21. let f = await Tree.findOne({ level: parseInt(event.queryStringParameters.level,10) }, "data");
  22. if (!f) { return res(""); }
  23. return res(f.data,"image/png");
  24. };

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

  1. ...
  2. UnityWebRequest www;
  3. if (l > 30) ll = 30; else ll = l;
  4. if (!T[ll - 1]){
  5. do {
  6. www = UnityWebRequestTexture.GetTexture(Apis.tree+"?level="+ll);
  7. yield return www.SendWebRequest();
  8. print(www.downloadedBytes + " Current: " + www.error);
  9. } while (www.error != null || www.downloadedBytes == 0);
  10. T[ll - 1] = DownloadHandlerTexture.GetContent(www);
  11. }
  12. 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:

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

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

Here is my current Lambda function:

  1. import { createRequire } from &#39;module&#39;;
  2. const require = createRequire(import.meta.url);
  3. const {Tree, config} = require(&#39;/opt/nodejs/models&#39;);
  4. const mongoose = require(&#39;mongoose&#39;);
  5. mongoose.set(&#39;strictQuery&#39;, true);
  6. await mongoose.connect(config.DB);
  7. function res(body, type=&quot;text/plain&quot;){
  8. const res = {
  9. statusCode: 200,
  10. isBase64Encoded: false,
  11. headers: {
  12. &quot;Access-Control-Allow-Origin&quot;:&quot;*&quot;,
  13. &quot;Content-Type&quot;: type
  14. },
  15. multiValueHeader: {},
  16. body
  17. };
  18. return res;
  19. }
  20. export const handler = async(event) =&gt; {
  21. let f = await Tree.findOne({ level: parseInt(event.queryStringParameters.level,10) }, &quot;data&quot;);
  22. if (!f) { return res(&quot;&quot;); }
  23. return res(f.data,&quot;image/png&quot;);
  24. };

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

  1. ...
  2. UnityWebRequest www;
  3. if (l &gt; 30) ll = 30; else ll = l;
  4. if (!T[ll - 1]){
  5. do {
  6. www = UnityWebRequestTexture.GetTexture(Apis.tree+&quot;?level=&quot;+ll);
  7. yield return www.SendWebRequest();
  8. print(www.downloadedBytes + &quot; Current: &quot; + www.error);
  9. } while (www.error != null || www.downloadedBytes == 0);
  10. T[ll - 1] = DownloadHandlerTexture.GetContent(www);
  11. }
  12. 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 部分,这是我的代码:

  1. do {
  2. www = UnityWebRequest.Get(Apis.tree + "?level=" + ll);
  3. yield return www.SendWebRequest();
  4. print(www.downloadedBytes + " Current: " + www.error);
  5. } while (www.error != null || www.downloadedBytes == 0);
  6. byte[] imageBytes = Convert.FromBase64String(www.downloadHandler.text);
  7. T[ll - 1] = new Texture2D(2048, 2048, TextureFormat.ARGB32, false);
  8. T[ll - 1].LoadImage(imageBytes);
  9. 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:

    1. do{
    2. www = UnityWebRequest.Get(Apis.tree+&quot;?level=&quot;+ll);
    3. yield return www.SendWebRequest();
    4. print(www.downloadedBytes + &quot; Current: &quot; + www.error);
    5. } while (www.error != null || www.downloadedBytes == 0);
    6. byte[] imageBytes = Convert.FromBase64String(www.downloadHandler.text);
    7. T[ll - 1] = new Texture2D(2048, 2048, TextureFormat.ARGB32, false);
    8. T[ll - 1].LoadImage(imageBytes);
    9. 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:

确定