How to properly compress images loaded with LoadImageIntoTexture?

I’m trying to download a bunch of images to an iPad3 with www.LoadImageIntoTexture. It works ok using www.texture, but images are uncompressed. Therefore, memory gets filled up quite quickly!

However, the application either crashes when using PVRTC or it complains when using DXT1 or 5: “WARNING: DXT texture format is not supported, decompressing texture”, which is ok because iOS does not support this format. It then simply loads images uncompressed…

Here’s how I’m doing it:

string photoURL = ApplicationPaths.Instance.StorageBasePath + "/" + url;

WWW www = new WWW(photoURL);
yield return www;
        
if (www.error != null) {
	Debug.Log (www.error);
}
else {
	GameObject albumThumbnail = Instantiate (albumThumbnailPrefab, Vector3.zero, Quaternion.identity) as GameObject;

	albumThumbnail.renderer.material.mainTexture = new Texture2D(
				www.texture.width, www.texture.height,
				TextureFormat.PVRTC_RGB2,
				false);
			
	www.LoadImageIntoTexture((Texture2D)albumThumbnail.renderer.material.mainTexture);
}

There’s something I’m missing, but I just don’t know what it is… I do need those textures to be compressed!

According to some other posts I’ve found, it’s not possible to load images into a compressed form in iOS. Also, it’s not possible to compress them once they are loaded. Trying this…

	Texture2D test = new Texture2D(
	www.texture.width, www.texture.height);
			
	www.LoadImageIntoTexture(test);
	test.Compress(false);
			
	albumThumbnail.renderer.material.mainTexture = test;
	Debug.Log (test.format);

shows DXT1 when running in the editor, but RGB24 when running on iOS.

I just don’t understand why. Precisely on a mobile platform where memory issues ARE a problem, I can’t load compressed textures. I hope I’m wrong, because this is a serious problem for the health of our current project…

The docs for Compress do explicitly say “Compress texture into DXT format.” Compression to PVRTC takes ages even on a desktop, and would take an eternity on the device. (Times being relative here. :wink: )

–Eric

DXT does not work on iOS, right? So that’s why compress does not work.

There’s no way to do this, and therefore the project is doomed. I can’t afford loading even two or three textures without compressing them somehow. I just can’t believe it…

A colleague of mine proposed to store the image in a file, then load it back. Who knows… I’ll try.

EDIT - nonsense, because I need www to load it back. ARGH.

You cannot compress to PVR on an iOS device… it would literally take like 10 minutes on an iPhone for one 1024x1024 textures.

You can compress PVR’s and package into assetBundles, then download and load them from the assetBundle. This works really well on iOS devices, without an issue.

When you do this you will want to build your AssetBundles uncompressed with BuildOptions.UncompressedAssetBundle setting. Then use the AssetBundle.CreateFromFile function to load the AssetBundle. On an iOS device this will open your AssetBundle without any memory overhead, and it will only take up memory for the textures you load.

You COULD write an Objective-C plugin to load PVR’s directly into your app. This is actually fully possible without doing anything ‘hacker’. However it would be quite involved.

Thanks, techmage, but AssetBundles are not an option. This app consists on users being able to take a photo and send it to an online gallery (and that can’t be done through AssetBundles, right?). Then they are able to browse that gallery and choose photos to play with them. And there’s when I need them to be compressed. Otherwise, either I use really small uncompressed thumbnails… or memory gets filled too fast.

I’m considering a totally different option, given that downloading images seems impossible: creating the whole gallery as a web page and showing it in a web view. But that’s a different matter.

You could build AssetBundles on server side from user uploaded pictures. It would of course take some processing time if there are lots of pictures to compress and build into bundles. Just saying that it is possible.

Thank you, MentalMoustache! That could certainly be an option, although much more… awkward than the web view. Managing assetbundles would certainly increase server costs! I think I’ll go for the webview, quite probably. I’ve tried showing something like Pinterest and it works like a charm.

An option, although maybe not ideal, would be to compress the textures into PVRTC format on your server. It is a command line tool that could be run on your thumbnail as a post-process step on the image upload. This approach would not scale well with more traffic.

If your just making a photo gallery, akin to the iPad’s built in photo gallery, then working with uncompressed textures is just fine. All you need is only one uncompressed texture loaded into memory at full size at any given point, the one the user is viewing. All the other can be unloaded, or loaded in at a fraction of the size… this is actually how iOS itself works. Internally, iOS is storing all of it’s raster data (anything on screen basically) as uncompressed in memory as well.

Well, yes, I do work with thumbnails. But even though, lots of small but uncompressed thumbnails take a lot of memory! A 320x240 RGB24 thumbnail takes around 230Kb. The same image, compressed to JPEG, takes 4Kb. Just ONE uncompressed thumbnail takes as much as FIFTY compressed thumbnails!

Using them in uncompressed format is not an option, I fear… don’t you think? Not if you expect many photos in that gallery!

Lets raise this zombie back to life and see where it goes.

Is it still not viable to keep the downloaded images as compressed on mobile in 2019?

To clarify, dynamically downloaded images via WWW create an uncompressed texture and if you download a lot of images, they eat the RAM for breakfast. I want to compress the texture after the image was downloaded and this is required on mobile devices too.

1 Like

Seconded!

1 Like