簡體   English   中英

Unity System.Drawing內部緩沖區溢出異常

[英]Unity System.Drawing Internal Buffer Overflow Exception

目標

從URL獲取統一工作的gif,我目前正在使用WWW類。 我目前正在獲取byte []並將其轉換為System.Drawing.Image。 這在編輯器中有效,但沒有任何構建

錯誤:

第111行的程序集“ System.Drawing.Image”中的“類型加載異常:無法加載類型” System.IO.InternalBufferOverflowException

為什么?

它與內置方法System.Drawing.Image.FromStream有關,由於某種原因,Unity不喜歡它。 其他選項是.FromFile和.FromHBitMap,我不知道如何使用HBitMap,但是回到我的原始計划,.FromFile對我來說不可用。

整個代碼

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;
    }
}

思考

  1. byteArrayIn.GetLongLength(0)最多返回80,000。
  2. 最后一條通過的調試語句稱為“映像加載回退”。
  3. 如有必要,我將編寫自己的防火旗,如果有必要,有人可以為此指出我的方向。
  4. 我認為主要的解決方法是處理Image.FromStream()。
  5. 場景中有兩個。

歡迎所有想法或解決方案,我真的只是希望我知道如何解決此錯誤,以便與Unity社區分享更多信息。

今天早上我們遇到了同樣的問題。

該應用程序未在System.Drawing.Image.所需的System.IO命名空間中找到類型System.Drawing.Image.

丟失的類型顯然已從構建過程中打包的system.dll中剝離。

要解決此問題,您需要將統一生成的System.dll復制並替換為原始的mono System.dll

在您的構建中,將projectName_Data\\Managed\\System.dll替換為在Unity的mono安裝文件夾中找到的System.dll

Editor\\Data\\Mono\\lib\\mono\\2.0 (相對於Unity安裝文件夾的根目錄)。

希望能幫助到你!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM