- Home /
Loading Images / Textures. Resources.Load() vs www.texture
Hi, I am making a project which has to load series of images of a system folder (C:/BLA_BLA/Image_Series/). In total there are about 500 images of 1400x500 aprox.
At first I tried using Resources.Load() and it worked very find, but in the release I can't use it because the images wouldn't be in the folder Resources... I also have tried using WWW but using it the images use a lot of memory, my code using this method is:
string imagePath = "file://C:/BLA_BLA/Image_Series/" + imageName + ".png"; WWW www = new WWW(imagePath); loadImageUrl(www);
newPlane.renderer.material.mainTexture = www.texture; Destroy(temp); www.Dispose(); www = null;
Note: Each texture loaded is for a different newPlane (a prefab of a plane).
IEnumerator loadImageUrl(WWW www) { yield return www;
if (www.error != null)
{
Debug.LogError("WWW Error: "+ www.error);
}
}
Loading the 3 same textures the 2 methods work: Using Resources.Load() -> 1 MB used textures and 10.3-11.4 MB VRAM usage. Using WWW -> 24 MB used textures and 10.3-34.4 MB VRAM usage.
Which is the cause of that difference? Do you have some ideas to reduce the used memory using WWW ? There is another, and best, way to load images?
Thank you!
Answer by Ashkan_gc · Oct 14, 2010 at 09:36 AM
when you import images in unity weather it's in resources folder or any other folder, the image will be compressed to a format (dxt most of the times) and then stored so they take less memory. using www you can only load jpg, png and i think bitmap images. you can compress them by hand yourself to reduce the memory or just compress the textures when you create them at runtime but it takes time so it's not recommended to do at runtime.
to create textures at runtime with the format that you want, you should load the texture with www("file::path") and then create another texture with the format that you want to do some getpixels/setpixels so it will take a huge time for 500 big textures.
the best approach is to compress your png/jpeg images then create a texture2D in DXT11 or DXT5 format then load the newly donwloaded texture into it with WWW.LoadImageIntoTexture.
in this way the texture will be compressed to DXT1 or 5 based on it's format. if you don't need a texture, don't forget to Destroy it.
i found this info in documentation of LoadImageIntoTexture method. it says
This function replaces texture contents with downloaded image data, so texture size and format might change. JPG files are loaded into RGB24 format, PNG files are loaded into ARGB32 format. If texture format before calling LoadImage is DXT1 or DXT5, then the loaded image will be DXT-compressed (into DXT1 for JPG images and DXT5 for PNG images).
the method that you used (using texture property of the www class) don't compress textures. also keep in mind that using none power of two textures will slow down the process but using this method you will be ok.
enjoy the awesome unity in any type of application.
I wanted to add that Unity Texture compression makes a dramatic loss of quality for nice 2D art you would like to put on GUI. So, this sounds great for 3D, but unsuited for GUI. This has unfortunately bothered me for a long time. I suggest using RGB24 or ARGB32 if GUI things need visual quality.
Answer by Daniel Cazan 1 · Oct 15, 2010 at 05:29 AM
Been beating my head against a wall all day and went through a lot of different posts, this one helped the most (thanks Ashkan for the direction), worked for me. Here's a quick demo-code I put together to test out and make sure the functionality worked.
In my script I manually put in a prefab for t_static_tx and loaded t_static_tx from a file (for comparison):
public Texture2D t_static_tx = null; public Texture2D t_dynamic_tx = null; public WWW t_load = null;
void OnGUI(){ GUI.Label(new Rect(100, 200, 64, 64), "TESTING"); GUI.Label(new Rect(164, 200, 64, 64), t_static_tx); if (t_load == null) { Debug.Log("Application data path: " + Application.dataPath); string targetFile = "file://" + Application.dataPath + "/Resources/Textures/Icons/Chairs_64x64.png"; Debug.Log("Beginning load at time: " + Time.time); t_load = new WWW(targetFile); } else if (t_load.isDone && t_dynamic_tx == null) { Debug.Log("File has finished being loaded at " + Time.time); t_dynamic_tx = new Texture2D(64, 64); Debug.Log("Preparing to load PNG into Texture"); t_load.LoadImageIntoTexture(t_dynamic_tx); Debug.Log("Loaded image into texture"); } else { GUI.Label(new Rect(164, 264, 64, 64), t_dynamic_tx); }
}
Answer by IJM · Oct 14, 2010 at 09:15 AM
As far as I know Unity puts the compression on bitmaps, so that is the reason. Compression is obviously happening in the process of building, it is obviously too demanding for real-time job. Have you tried Asset Bundles?
Answer by verdegang 1 · Oct 18, 2010 at 06:12 PM
Hi again, and thank you for your answers!!
I've been working a bit and I have news.
IJM I can't use Asset Bundles because the images will be entered by the user, so it wouldn't be compiled with the project.
Ashkan Finally I've usedWWW.LoadImageIntoTexture. But it has appeared a problem creating a Texture2D in DXT11 or DXT5 format. I create it using:
Texture2D t = new Texture2D(2, 2, TextureFormat.DXT1, false);
But in that line, Unity crashes with that error:
UnityException: Failed to create texture (can't create with compressed format).
UnityEngine.Texture2D..ctor (Int32 width, Int32 height, TextureFormat format, Boolean mipmap) (at E:/BuildAgent/work/68355d6e5d19d587/Runtime/Export/Generated/Graphics.cs:926)
ImageLoader.loadImage (Vector3 position, Int32 imageNumber) (at Assets/Scripts/ImageLoader.cs:126)
ImageLoader.loadImages () (at Assets/Scripts/ImageLoader.cs:157)
ImageLoader.Start () (at Assets/Scripts/ImageLoader.cs:24)
To solve this problem and create a compressed texture I've created it using:
Texture2D t = new Texture2D(2, 2);
www.LoadImageIntoTexture(t);
t.Compress(true);
Another important question is that t.Compress only works if I use textures in resolution 2^x * 2^x (for example 512x512), so I have to scale all the textures on a power of two resolution.
Anybody knows a method to Compress all kind of resolutions?
This is a very old question, so apologies for bumping it, but for anyone that comes across this:
Compress does not work on very small images, because they can't be compressed. Compressing a 2x2 image isn't going to make it any smaller.
The LoadImageIntoTexture will replace the current image in there so the 2x2 is a red herring, the image won't be that size after the www.LoadImageIntoTexture call.
I'm having a very similar problem and running the iPhone out of texture memory - I also can't seem to get the DXT formats to work with the same error message, worrying that this topic is so old, but still appears to be a problem.
The biggest challenge seems to be any kind of manipulation of an image on the client side due to there being no implementation of the drawing libraries - so everything ends up being SetPixel which is pretty time consu$$anonymous$$g.
The iPhone doesn't support DXT textures: http://unity3d.com/support/documentation/Components/class-Texture2D.html which is why you'll not be able to directly load them as DXT
Answer by samra2494 · Nov 01, 2017 at 11:45 AM
this code will help you
string WebUrl , ServerUrl; public Image Web_image , ServerImage; Texture2D tex; WWW Link;
IEnumerator LoadImageInternet()
{
tex = new Texture2D(4, 4, TextureFormat.DXT1 , false);
Link = new WWW (WebUrl);
yield return Link;
Link.LoadImageIntoTexture (tex);
Web_image.sprite = Sprite.Create (tex, new Rect (0, 0, tex.width, tex.height), new Vector2 (0, 0));
}
//Button Event
public void LoadFromInternet()
{
WebUrl = "https://upload.wikimedia.org/wikipedia/commons/d/dc/Cats_Petunia_and_Mimosa_2004.jpg";
StartCoroutine (LoadImageInternet ());
}