Расшифруйте изображение JPEG в потоке C # в Unity - PullRequest
0 голосов
/ 02 марта 2019

У меня есть приложение Unity, в котором движок постоянно зависает, когда я загружаю большое изображение с помощью LoadImage.

Поэтому я решил попробовать декодировать изображение в отдельном потоке из основного потока.Я использую C # JPEG декодер отсюда

https://gist.github.com/jandk/3889823

Я написал тестовый код, чтобы проверить его.Тестовый код раскручивает куб в основном потоке.Пока куб вращается, я создаю отдельный поток, в котором изображение JPG загружается с веб-сайта и декодируется.После декодирования главный поток берет эти декодированные биты и применяет их к кубу, используя LoadRawImageData

Идея использования вращающегося куба заключается в том, что любое зависание двигателя, вызванное обработкой изображения, будет легко увидеть, потому что кубна мгновение перестанет вращаться.

Вот код

 using System.Collections;     
 using System.Collections.Generic;
 using UnityEngine;
 using System.Threading;
 using System.Net;
 using UnityEngine.UI;
 using System.IO;
 using Unity.Collections;
 using UnityEngine.Networking;
 using Jpeg;

 public class Spin : MonoBehaviour
 {

class ThreadedImageLoader : MonoBehaviour
{
    public Thread thread = null;
    public byte[] pixels = null;
    public string url;
    public bool done = false;
    public GameObject g;

    public void Download(string url,GameObject g)
    {
        this.url = url;
        this.g = g;

        Debug.Log("Downloading from url=" + url);

        thread = new Thread(() => DoThread());
        thread.Start();
    }

    public void DoThread()
    {
        Debug.Log("downloading pic on a thread");
        HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create(url);
        string lsResponse = string.Empty;
        using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse()) {
            using (BinaryReader reader = new BinaryReader(lxResponse.GetResponseStream())) {
                pixels = reader.ReadBytes(1 * 1024 * 1024 * 10);
            }
        }
        Debug.Log("Done downloading, creating decoder...");
        JpegDecoder jdec = new JpegDecoder(pixels);
        Debug.Log("decoder created, decompressing...");
        byte[] img = jdec.DecodeScan();
        Debug.Log("Done decompressing");
        done = true;
    }
}

List<ThreadedImageLoader> loaders = new List<ThreadedImageLoader>();
public float delta = 1f;

void Start()
{
    string url = "https://www.gstatic.com/webp/gallery/4.jpg";
    ThreadedImageLoader td = gameObject.AddComponent<ThreadedImageLoader>();
    loaders.Add(td);
    td.Download(url,gameObject);
}

void Update()
{
    float d = delta * Time.deltaTime;
    transform.Rotate(new Vector3(d, d, d));
    if (loaders.Count > 0) {
        ThreadedImageLoader td = (ThreadedImageLoader)loaders[0];
        if (td.done) {
            Debug.Log("Update:pixels lenth:" + td.pixels.Length);
            if (td.pixels.Length > 0) {
                Texture2D t = new Texture2D(1, 1);
                t.LoadRawTextureData(td.pixels);
                t.Apply();
                gameObject.GetComponent<Renderer>().material.mainTexture = t;
            }

            loaders.RemoveAt(0);
            Destroy(td);

            // keep downloading the image again
            string url = "https://www.gstatic.com/webp/gallery/4.jpg";
            ThreadedImageLoader tdd = gameObject.AddComponent<ThreadedImageLoader>();
            loaders.Add(tdd);
            tdd.Download(url,gameObject);
        }
    }
}
 }

При запуске кода куб начинает вращаться, создается нить, изображение загружается по ссылке, ноКогда создается декодер JPEG, он падает внутри декодера с ошибкой чтения изображения.

Используемый им декодер jpeg находится по этой ссылке выше.Кажется очень простым, только один файл, но он останавливает декодирование с ошибкой при чтении загруженных данных.

Я знаю, что загруженные данные изображения верны, потому что если я использую LoadImage (пиксели) для тех же данных, то изображение появляетсяв совершенстве.Конечно, я не могу использовать Loadimage в реальном коде, потому что он замораживает основной поток, потому что он декодирует изображение в основном потоке (что вызывает зависание).

Кто-нибудь знает лучший декодер c # jpeg, который я могу использоватьв этом случае?тот, который может работать в потоке и не имеет много зависимостей, увеличивающих раздувание?Мне просто нужно, чтобы он был в состоянии декодировать JPEG в потоке в Unity.

Я попробовал несколько пакетов nuget, но не могу заставить их правильно установить в Unity.По этой ссылке был единственный файл-декодер, который мне было легко найти, но он, конечно, завис!

Спасибо за любую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...