unity 加载网络图片

摘要:利用Http加载网络图片。

解决思路:

1、直接用unity 自带的www加载,在高版本www已经过时了。

2、本文直接使用万能的文件流加载。

(1)使用System.Net.HttpWebRequest 请求网络流。

(2)利用System.Drawing这个dll把网络流装载到内存。可以获取远程网络图片的基本信息,图片宽高,格式等。如果已经知道远程图片数据,可以先把网络流拷贝到内存,直接对流进行操作。

(3)Texture2D.LoadImage显示图片

废话不多说,直接上代码

获取网络图片二进制数据:

 1 public struct RemoteImageMessage
 2 {
 3     public int Width;
 4 
 5     public int Height;
 6 
 7     public byte[] DataSource;
 8 }
 9 
10 public static class ImageDownloadHelper
11 {
12     /// <summary>
13     /// 获取远程图片
14     /// </summary>
15     /// <param name="imgPath"></param>
16     /// <param name="complete"></param>
17     public static void GetImage(string imgPath, Action<RemoteImageMessage> complete)
18     {
19         System.Threading.Tasks.Task.Run(() =>
20         {
21             RemoteImageMessage remoteImageMessage = new RemoteImageMessage();
22             try
23             {
24                 System.Net.HttpWebRequest webRequest = System.Net.WebRequest.CreateHttp(imgPath);
25                 using (var response = webRequest.GetResponse())
26                 {
27                     if (response.ContentLength != 0)
28                     {
29                         System.IO.Stream stream = response.GetResponseStream();
30                         System.Drawing.Image image = System.Drawing.Image.FromStream(stream);
31                         remoteImageMessage.Width = image.Width;
32                         remoteImageMessage.Height = image.Height;
33                         var bytes = ImageToBytes(image);
34                         remoteImageMessage.DataSource = bytes;
35                         stream.Close();
36                         stream.Dispose();
37                     }
38                 }
39             }
40             catch (Exception ex)
41             {
42                 Debug.LogError("加载图片出错!" + ex);
43             }
44             finally
45             {
46                 complete?.Invoke(remoteImageMessage);
47             }
48         });
49     }
50 
51     /// <summary>
52     /// Image 转bytes
53     /// </summary>
54     /// <param name="image"></param>
55     /// <returns></returns>
56     private static byte[] ImageToBytes(System.Drawing.Image image)
57     {
58         System.Drawing.Imaging.ImageFormat format = image.RawFormat;
59         using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
60         {
61             if (format.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
62             {
63                 image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
64             }
65             else if (format.Equals(System.Drawing.Imaging.ImageFormat.Png))
66             {
67                 image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
68             }
69             else if (format.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
70             {
71                 image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
72             }
73             else if (format.Equals(System.Drawing.Imaging.ImageFormat.Gif))
74             {
75                 image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
76             }
77             else if (format.Equals(System.Drawing.Imaging.ImageFormat.Icon))
78             {
79                 image.Save(ms, System.Drawing.Imaging.ImageFormat.Icon);
80             }
81             byte[] buffer = new byte[ms.Length];
82             //Image.Save()会改变MemoryStream的Position,需要重新Seek到Begin
83             ms.Seek(0, System.IO.SeekOrigin.Begin);
84             ms.Read(buffer, 0, buffer.Length);
85             return buffer;
86         }
87     }
88 
89 }

在unity中显示

 1 public class ImageLoaderHeler : MonoBehaviour
 2 {
 3     private RawImage rawImage = null;
 4 
 5     private string[] imageUrl = new string[]
 6     {   "http://t8.baidu.com/it/u=2247852322,986532796&fm=79&app=86&f=JPEG?w=1280&h=853",
 7         "http://t9.baidu.com/it/u=3363001160,1163944807&fm=79&app=86&f=JPEG?w=1280&h=830",
 8         "http://t9.baidu.com/it/u=583874135,70653437&fm=79&app=86&f=JPEG?w=3607&h=2408",
 9         "http://t9.baidu.com/it/u=2268908537,2815455140&fm=79&app=86&f=JPEG?w=1280&h=719",
10         "http://t7.baidu.com/it/u=1179872664,290201490&fm=79&app=86&f=JPEG?w=1280&h=854",
11         "http://t9.baidu.com/it/u=3923875871,1613462878&fm=79&app=86&f=JPEG?w=1280&h=854",
12         "http://t9.baidu.com/it/u=3949188917,63856583&fm=79&app=86&f=JPEG?w=1280&h=875",
13         "http://t7.baidu.com/it/u=1355385882,1155324943&fm=79&app=86&f=JPEG?w=1280&h=854",
14         "http://t8.baidu.com/it/u=2857883419,1187496708&fm=79&app=86&f=JPEG?w=1280&h=763",
15         "http://t7.baidu.com/it/u=830740827,3648735644&fm=79&app=86&f=JPEG?w=1280&h=853",
16         "http://t8.baidu.com/it/u=198337120,441348595&fm=79&app=86&f=JPEG?w=1280&h=732",
17         "http://t9.baidu.com/it/u=1577456063,1344044640&fm=79&app=86&f=JPEG?w=1280&h=853",
18         "http://t8.baidu.com/it/u=2678662753,1297312162&fm=79&app=86&f=JPEG?w=1181&h=787",
19         "http://t8.baidu.com/it/u=2148738019,2920001333&fm=79&app=86&f=JPEG?w=1181&h=788",
20         "http://t9.baidu.com/it/u=1373840141,993565751&fm=79&app=86&f=JPEG?w=1181&h=788"
21     };
22 
23     // Start is called before the first frame update
24     void Start()
25     {
26         rawImage = GetComponent<RawImage>();
27         //InvokeRepeating("Test", 3, 0.5f);
28     }
29 
30 
31     private int index = 0;
32 
33     private void Test()
34     {
35         if (index >= imageUrl.Length)
36         {
37             index = 0;
38         }
39         LoadImage(imageUrl[index++]);
40     }
41 
42     private void LoadImage(string imagePath)
43     {
44         var start = DateTime.Now;
45         Debug.LogError("图片数据开始加载!");
46         ImageDownloadHelper.GetImage(imagePath, (image) =>
47          {
48              ThreadCrossor.GetInstance()?.AddTaskToMainThread(() =>
49              {
50                  var ori = rawImage.texture;
51                  if (ori != null)
52                  {
53                      DestroyImmediate(ori);
54                      rawImage.texture = null;
55                  }
56                  Debug.LogError($"图片尺寸{image.Width},{image.Height}");
57                  Texture2D texture2D = new Texture2D(image.Width, image.Height);
58                  texture2D.LoadImage(image.DataSource);
59                  rawImage.texture = texture2D;
60              });
61              Debug.LogError($"完成图片加载!加载时间:{(DateTime.Now - start).TotalSeconds}s");
62          });
63     }
64 
65   
66     // Update is called once per frame
67     void Update()
68     {
69        
70     }
71 }

写了一个简单的跨线程交互的类

public class ThreadCrossor : MonoBehaviour
{
    private static ThreadCrossor threadCrossor = null;

    List<Action> actions = new List<Action>();

    public static ThreadCrossor GetInstance()
    {
        return threadCrossor;
    }

    /// <summary>
    /// 往主进程添加任务
    /// </summary>
    /// <param name="action"></param>
    public void AddTaskToMainThread(Action action)
    {
        lock (actions)
        {
            actions.Add(action);
        }
    }

    // Start is called before the first frame update
    void Start()
    {
        threadCrossor = this;
    }

    // Update is called once per frame
    void Update()
    {
        lock (actions)
        {
            if (actions.Count > 0)
            {
                foreach(var action in actions)
                {
                    action?.Invoke();
                }
                actions.Clear();
            }
        }
    }
}

效果如下:

posted @ 2020-06-01 11:01  荀幽  阅读(3120)  评论(0编辑  收藏  举报