Unity WebGl StackOverFlow

时间:2017-05-31 14:25:05

标签: unity3d unity-webgl

一天中的好时光,我想从用户本地计算机加载任何大小的图像到Unity Web应用程序。我搜索this article但我经常得到#stack; flowoverflow"我尝试加载大尺寸图片时出现异常。

我得到" stackoverflow"在这次电话会议之后。

  

sendResult(dataUrl);

这是统一网络插件代码:

var UnityBridge = {
LoadImage: function()
{
    // Because unity is currently bad at JavaScript we can't use standard
    // JavaScript idioms like closures so we have to use global variables :(
    window.becauseUnitysBadWithJavacript_getImageFromBrowser =
        window.becauseUnitysBadWithJavacript_getImageFromBrowser || {
            busy: false,
            initialized: false,
            rootDisplayStyle: null,  // style to make root element visible
            root_: null,             // root element of form
            ctx_: null              // canvas for getting image data;
        };
    var g = window.becauseUnitysBadWithJavacript_getImageFromBrowser;
    if (g.busy) {
        // Don't let multiple requests come in
        return;
    }
    g.busy = true;

    if (!g.initialized) {
        g.initialized = true;
        g.ctx = window.document.createElement("canvas").getContext("2d");

        // Append a form to the page (more self contained than editing the HTML?)
        g.root = window.document.createElement("div");
        g.root.innerHTML = [
        '<style>                                                    ',
        '.getimage {                                                ',
        '    position: absolute;                                    ',
        '    left: 0;                                               ',
        '    top: 0;                                                ',
        '    width: 100%;                                           ',
        '    height: 100%;                                          ',
        '    display: -webkit-flex;                                 ',
        '    display: flex;                                         ',
        '    -webkit-flex-flow: column;                             ',
        '    flex-flow: column;                                     ',
        '    -webkit-justify-content: center;                       ',
        '    -webkit-align-content: center;                         ',
        '    -webkit-align-items: center;                           ',
        '                                                           ',
        '    justify-content: center;                               ',
        '    align-content: center;                                 ',
        '    align-items: center;                                   ',
        '                                                           ',
        '    z-index: 2;                                            ',
        '    color: white;                                          ',
        '    background-color: rgba(0,0,0,0.8);                     ',
        '    font: sans-serif;                                      ',
        '    font-size: x-large;                                    ',
        '}                                                          ',
        '.getimage a,                                               ',
        '.getimage label {                                          ',
        '   font-size: x-large;                                     ',
        '   background-color: #666;                                 ',
        '   border-radius: 0.5em;                                   ',
        '   border: 1px solid black;                                ',
        '   padding: 0.5em;                                         ',
        '   margin: 0.25em;                                         ',
        '   outline: none;                                          ',
        '   display: inline-block;                                  ',
        '}                                                          ',
        '.getimage input {                                          ',
        '    display: none;                                         ',
        '}                                                          ',
        '</style>                                                   ',
        '<div class="getimage">                                     ',
        '    <div>                                                  ',
        '      <label for="photo">Кликните чтобы выбрать изображенние</label>  ',
        '      <input id="photo" type="file" accept="image/*"/><br/>',
        '      <a>Отмена</a>                                        ',
        '    </div>                                                 ',
        '</div>                                                     ',
        ].join('\n');
        var input = g.root.querySelector("input");
        input.addEventListener('change', getPic);

        // prevent clicking in input or label from canceling
        input.addEventListener('click', preventOtherClicks);
        var label = g.root.querySelector("label");
        label.addEventListener('click', preventOtherClicks);

        // clicking cancel or outside cancels
        var cancel = g.root.querySelector("a");  // there's only one
        cancel.addEventListener('click', handleCancel);
        var getImage = g.root.querySelector(".getimage");
        getImage.addEventListener('click', handleCancel);

        // remember the original style
        g.rootDisplayStyle = g.root.style.display;

        window.document.body.appendChild(g.root);
    } 

    // make it visible
    g.root.style.display = g.rootDisplayStyle;

    function preventOtherClicks(evt) {
        evt.stopPropagation();
    }
    function getPic(evt) {
        evt.stopPropagation();
        var fileInput = evt.target.files;
        if (!fileInput || !fileInput.length) {
            return sendError("no image selected");
        }

        var picURL = window.URL.createObjectURL(fileInput[0]);
        var img = new window.Image();
        img.addEventListener('load', handleImageLoad);
        img.addEventListener('error', handleImageError);
        img.src = picURL;

    }

    function handleCancel(evt) {
        evt.stopPropagation();
        evt.preventDefault();
        sendError("cancelled");
    }

    function handleImageError(evt) {
        sendError("Could not get image");
    }

    function handleImageLoad(evt) {
        var img = evt.target;
        console.log(img);
        window.URL.revokeObjectURL(img.src);
        // We probably don't want the fullsize image. It might be 3000x2000 pixels or something too big
        const screenWidth = 1280;
        const screenHeight = 800;

        g.ctx.canvas.width = img.width;
        g.ctx.canvas.height = img.height;
        console.log("Image width: " + img.width + " height: " + img.height);
        coefficientWidth = screenWidth / img.width;
        coefficientHeight = screenHeight / img.height;

        if (g.ctx.canvas.width > screenWidth || g.ctx.canvas.height > screenHeight) {
        // scale image if it bigger UnityPlayer
            if (coefficientWidth < coefficientHeight) {
            g.ctx.canvas.width *= coefficientWidth;
            g.ctx.canvas.height *= coefficientWidth;
            console.log("if width > height then canvas width : " + g.ctx.canvas.width + " height: " + g.ctx.canvas.height);
           } else {
            g.ctx.canvas.width *= coefficientHeight;
            g.ctx.canvas.height *= coefficientHeight;
            console.log("if width < height then canvas width : " + g.ctx.canvas.width + " height: " + g.ctx.canvas.height);
           }
        }
        g.ctx.drawImage(img, 0, 0, g.ctx.canvas.width, g.ctx.canvas.height);

        console.log("This is dataUrl: " + g.ctx.canvas.toDataURL());

        var dataUrl = g.ctx.canvas.toDataURL();

        // free the canvas memory (could probably be zero)
        g.ctx.canvas.width  = 1;
        g.ctx.canvas.height = 1;

        sendResult(dataUrl);
        g.busy = false;
    }

    function sendError(msg) {
        sendResult("error: " + msg);
    }

    function hide() {
        g.root.style.display = "none";
    }

    function sendResult(result) {
        hide();
        g.busy = false;
        SendMessage("NativeBridge", "OnPick", result);
    }
}
};

mergeInto(LibraryManager.library, UnityBridge);

请帮帮我。

1 个答案:

答案 0 :(得分:0)

您必须将从 js 发送回的字符串分成块,因为 Unity 无法处理非常大的字符串。做这样的事情:

      function sendResult(result,offset) {
      hide();
      g.busy = false;
      //Split string into smaller chunks as Unity is too retarded to do it properly with large strings
      var bufferSize=100000;
      for (var x = offset; x < result.length; x+=bufferSize) 
      {
        SendMessage(objectName, funcName, result.substring(x,Math.min(x+bufferSize,result.length)));
      } 
      //Send EOF
      SendMessage(objectName, funcName, 'EOF:');
  }

然后在Unity中的接收代码中,是这样的:

    private StringBuilder buffer = null;
public void receiveFile(string input)
{
    if (input.StartsWith("ERROR:"))
    {
        buffer = null;
        Debug.LogError(input);
        return;
    }

    if (input.StartsWith("EOF:"))
    {
        string bufferText = buffer.ToString();
        buffer = null;
        byte[] data = System.Convert.FromBase64String(bufferText);
        //Do something with data...
        return;
    }
    else
    {
        if (buffer == null) buffer = new StringBuilder();
        buffer.Append(input);
    }
}