Unity系统.绘图内部缓冲区溢出异常

本文关键字:溢出 异常 缓冲区 内部 系统 绘图 Unity | 更新日期: 2023-09-27 18:16:57

目标

从URL获取一个统一工作的gif,我目前正在使用WWW类。我目前正在获取一个字节[]并将其转换为System.Drawing.Image。这在编辑器中有效,但在任何构建中都无效

错误:

类型加载异常:无法从程序集"System.Drawing.Image"的第111行加载类型"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(最多返回80000
  2. 最后一个调试语句是Called Image Loading BACK
  3. 如果有必要,我会写我自己的fire streamer,如果有必要的话,有人能为我指明写作方向吗
  4. 我认为主要的解决方法是处理Image.FromStream((
  5. 场景中有两个

欢迎所有想法或解决方案,我真的只希望我知道如何解决这个错误,这样我就可以与团结社区分享更多。

Unity系统.绘图内部缓冲区溢出异常

我们今天早上也遇到了同样的问题。

应用程序在System.Drawing.Image. 所需的System.IO命名空间中找不到类型

缺失的类型显然已从构建过程中打包的system.dll中剥离。

要修复此问题,您需要复制unity生成的System.dll并将其替换为原始单声道System.dll

在您的构建中,用Unity的mono安装文件夹中的System.dll替换projectName_Data'Managed'System.dll

Editor'Data'Mono'lib'mono'2.0(相对于Unity安装文件夹的根目录(。

希望它能有所帮助!