简体   繁体   English

Unity System.Drawing内部缓冲区溢出异常

[英]Unity System.Drawing Internal Buffer Overflow Exception

Goal 目标

Get a gif working in unity from a URL, I am currently using the WWW class. 从URL获取统一工作的gif,我目前正在使用WWW类。 I am currently getting a byte[] and converting it to a System.Drawing.Image. 我目前正在获取byte []并将其转换为System.Drawing.Image。 This works in the editor but not any build 这在编辑器中有效,但没有任何构建

Error: 错误:

"Type Load Exception: Could not load type" System.IO.InternalBufferOverflowException from the assembly "System.Drawing.Image" at line 111 第111行的程序集“ System.Drawing.Image”中的“类型加载异常:无法加载类型” System.IO.InternalBufferOverflowException

Why? 为什么?

It has to do with the System.Drawing.Image.FromStream built in method, Unity for some reason doesn't like it. 它与内置方法System.Drawing.Image.FromStream有关,由于某种原因,Unity不喜欢它。 The other options are .FromFile and .FromHBitMap, I dont know how to use HBitMap but going back to my original plan, .FromFile is unusable to me. 其他选项是.FromFile和.FromHBitMap,我不知道如何使用HBitMap,但是回到我的原始计划,.FromFile对我来说不可用。

Entire Code 整个代码

using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using UnityEngine;
using System.IO;
using UnityEngine.UI;
using System.Collections;

public class AnimatedGifDrawerBack : MonoBehaviour
{
    public string loadingGifPath;
    public float speed = 1;
    public Vector2 drawPosition;
    public string pName;

    public float width;
    public float height;
    public float percentage;
    public GameObject positionPlaceHolderGO;
    public Vector2 positionPlaceHolder;
    public Text debugText;
    private SpriteImageArray sia;
    private string url;
    private WWW www;
    public bool finishedWWW = false;
    public bool hasWWW = false;
    public bool canOnGUI = false;

    List<Texture2D> gifFrames = new List<Texture2D>();

    void Start()
    {


        percentage = 1.3f;
        positionPlaceHolderGO = GameObject.FindGameObjectWithTag("PBLPlace");
        positionPlaceHolder = positionPlaceHolderGO.transform.position;

    }

    void Update()
    {
        while (hasWWW == false)
        {
            Debug.Log("in while loop");
            if (this.GetComponent<PokemonCreatorBack>().name == "")
            {

            }
            else
            {
                debugText.text = "Name Found";
                url = "www.pkparaiso.com/imagenes/xy/sprites/animados-espalda/" + this.GetComponent<PokemonCreatorBack>().PokemonName.ToLower() + ".gif";

                StartCoroutine(WaitForRequest(positionPlaceHolderGO, url));
                hasWWW = true;
                debugText.text = "hawWWW = true";
            }
        }
    }

    void OnGUI()
    {
        height = (float)Screen.height - 80f / percentage;

        //GUI.DrawTexture (new Rect (Screen.width-width, Screen.height - height, gifFrames [0].width * percentage, gifFrames [0].height * percentage), gifFrames [(int)(Time.frameCount * speed) % gifFrames.Count]);
        if (canOnGUI)
            GUI.DrawTexture(new Rect(positionPlaceHolder.x, positionPlaceHolder.y, gifFrames[0].width * percentage, gifFrames[0].height * percentage), gifFrames[(int)(Time.frameCount * speed) % gifFrames.Count]);

    }

    IEnumerator WaitForRequest(GameObject go, string url)
    {
        www = new WWW(url);
        yield return www;
        if (www.error == null)
        {
            Debug.Log("WWW Ok!: " + www.texture.name);
        }
        else
        {
            Debug.Log("WWW Error: " + www.error);
        }
        debugText.text = "finishedWWW = true";
        finishedWWW = true;
    }

    public System.Drawing.Image ByteArrayToImage(byte[] byteArrayIn)
    {
        if (finishedWWW == false)
        {
            Debug.Log("Called too early");
        }
        if (byteArrayIn == null)
        {
            Debug.Log("Null byte array");
            return null;
        }
        Debug.Log("Bytra array in length: " + byteArrayIn.GetLongLength(0));
        MemoryStream ms = new MemoryStream(byteArrayIn);
        System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);     //MAIN SOURCE OF ERROR HERE
        finishedWWW = true;
        debugText.text = "System.Image Created";
        return returnImage;
    }

    public void loadImage()
    {
        Debug.Log("Called Load Image BACK");
        debugText.text = "Called Load Image BACK";
        System.Drawing.Image gifImage = ByteArrayToImage(www.bytes);


        FrameDimension dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
        int frameCount = gifImage.GetFrameCount(dimension);
        for (int i = 0; i < frameCount; i++)
        {
            gifImage.SelectActiveFrame(dimension, i);
            Bitmap frame = new Bitmap(gifImage.Width, gifImage.Height);
            System.Drawing.Graphics.FromImage(frame).DrawImage(gifImage, Point.Empty);
            Texture2D frameTexture = new Texture2D(frame.Width, frame.Height);
            for (int x = 0; x < frame.Width; x++)
                for (int y = 0; y < frame.Height; y++)
                {
                    System.Drawing.Color sourceColor = frame.GetPixel(x, y);
                    frameTexture.SetPixel(frame.Width - 1 + x, -y, new Color32(sourceColor.R, sourceColor.G, sourceColor.B, sourceColor.A)); // for some reason, x is flipped
                }
            frameTexture.Apply();
            gifFrames.Add(frameTexture);
        }
        Debug.Log("Starting ON GUI!");
        debugText.text = "Starting OnGUI";
        canOnGUI = true;
    }
}

Thoughts 思考

  1. byteArrayIn.GetLongLength(0) returns 80,000 at most. byteArrayIn.GetLongLength(0)最多返回80,000。
  2. The last debug statement coming through is Called Image Loading BACK. 最后一条通过的调试语句称为“映像加载回退”。
  3. I will write my own fire streamer if necessary, and if it is necessary can someone point me in the write direction for that. 如有必要,我将编写自己的防火旗,如果有必要,有人可以为此指出我的方向。
  4. I think the main workaround is dealing with the Image.FromStream(). 我认为主要的解决方法是处理Image.FromStream()。
  5. There are two of these in the scene. 场景中有两个。

All thoughts or solutions are welcome, I really just wish I knew how to tackle this error so that I could share it more with the Unity Community. 欢迎所有想法或解决方案,我真的只是希望我知道如何解决此错误,以便与Unity社区分享更多信息。

We faced the same problem this morning. 今天早上我们遇到了同样的问题。

The app is not finding a type in the System.IO namespace required by System.Drawing.Image. 该应用程序未在System.Drawing.Image.所需的System.IO命名空间中找到类型System.Drawing.Image.

The missing type has apparently been stripped from the system.dll that is packed during the build process. 丢失的类型显然已从构建过程中打包的system.dll中剥离。

To fix this, you need to copy and replace the unity generated System.dll with the original mono System.dll . 要解决此问题,您需要将统一生成的System.dll复制并替换为原始的mono System.dll

In your build, replace projectName_Data\\Managed\\System.dll with the System.dll found in Unity's mono installation folder: 在您的构建中,将projectName_Data\\Managed\\System.dll替换为在Unity的mono安装文件夹中找到的System.dll

Editor\\Data\\Mono\\lib\\mono\\2.0 (relative to the root of the Unity installation folder). Editor\\Data\\Mono\\lib\\mono\\2.0 (相对于Unity安装文件夹的根目录)。

Hope it helps! 希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM