- Home /
Texture2d.LoadImage too slow for use (iOS)
I am working on a project which downloads png files from a web server and loads them into a Texture2D for use.
The following code highlights a very severe problem with the Teture2D LoadImage method. Namely, it takes 250ms to load a 500x500 pixel texture.
DateTime nowTime = DateTime.Now;
string completedPath = "A local path"
byte [] textureData = File.ReadAllBytes(completedPath);
Debug.Log ("Loading bytes " + (DateTime.Now - nowTime).TotalMilliseconds + "ms");
nowTime = DateTime.Now;
Texture2D tex = new Texture2D(0,0);
tex.LoadImage(textureData);
Debug.Log ("Loading texture " + (DateTime.Now - nowTime).TotalMilliseconds + "ms");
The output from this code is as follows (When run on an iPhone 4):
Loading bytes 10.187ms
Loading texture 235.297ms
Is there a faster way to load a png from disk? This seems like a ridiculous amount of time to take to load a simple image. If possible I would like to avoid the use of Asset Bundles.
As a comparison. Loading the same texture on the same device (iPhone 4) using pure objective C takes 10 ms.
float timeNow = CACurrentMediaTime();
UIImage *image = [UIImage imageNamed:@"brand1365761681365.png"];
NSLog(@"Time taken on ios %f ms", (CACurrentMediaTime() - timeNow)*1000.f);
Time taken on ios 10.370380ms
Loading the texture using the WWW class takes even longer, around 1000ms.
Well it's load an image, convert it into an expanded format and upload it to the graphics hardware - which is unfortunately a slow process.
Have you tried:
var www = new WWW("file:///some path/file.png"); //for a local path
yield return www;
var someTexture = www.texture;
As a comparison, loading the same texture on the same device using pure objective c takes 10 milliseconds. So the problem is not with loading it, it is to do with Unity's implementation of png loading.
See this Objective-C example:
float timeNow = CACurrent$$anonymous$$ediaTime();
UIImage *image = [UIImage imageNamed:@"brand1365761681365.png"];
NSLog(@"Time taken on ios %f ms", (CACurrent$$anonymous$$ediaTime() - timeNow)*1000.f);
Gives the following: Time taken on ios 10.370380 ms
Using an asset bundle to download from a "file://" link takes 1067.993ms for the same file on the same device.
I will update my question with this data.
Well it's doing a different thing with it - as in uploading it as a texture to the graphics card not rendering it in place as a PNG like a browser or other app might.
What are you talking about? Texture2D.LoadImage creates a Texture (to use for rendering) out of a png. Loading from an asset bundle, or from the WWW class will also do the same thing. The code I posted for iOS does exactly the same thing but for use in iOS obviously.
Loading a texture with Unity should not be 25 times slower than loading the same texture in iOS.
A Texture2D is not a UIImage.
A Texture2D has code for accessing the image internally for read write and also as an image for an OpenGL context - who knows what it's doing behind the scenes, but it could well be doing more work than reading it directly from a WWW that has downloaded it (especially as all of that will be happening in the C++). You can also use WWW.textureNonReadable which will incur a lower memory footprint and may also be faster.
Loading from an Asset Bundle (which I wasn't suggesting) will not be loading a PNG at all, but the already decompressed and coded for iOS version of the image. Perhaps as a raw file, perhaps PVRTC compressed depending on how you have the asset configured before building the bundle.
Answer by whydoidoit · Aug 09, 2013 at 12:33 PM
Using LoadImage on a Texture2D on the device is a lot slower than it is in the editor and as @OwenW and I found out through experiments in the comments to the question, WWW is an order of magnitude faster.
Use:
var www = new WWW("file://" + path);
var texture = www.textureNonReadable;
Rather than creating a Texture2D and using LoadImage when working on iOS.
Using .texture cuts the load time for me down from 250ms to 50ms, .textureNonReadable cuts this down further to under 20ms.
Are you profiling this on a device or in the editor? In the editor, i don't see this having any effect at all (on execution time), except for the fact that heap memory is not allocated for this. Execution time is roughly the same ...
Your answer
Follow this Question
Related Questions
iOS OnGUI vs Update for color picker 2 Answers
Performance and memory using sprites 1 Answer
Coin Magnet Performance Issue Mobile 3 Answers
Mobile game - should I reduce my vertex count? 1 Answer
Slow Load Time for iOS App 0 Answers