Creating a Texture from an SDCard File

Hello everyone and thank you in advance for any help. I’m hoping to use jME for a project I’m working on, and the engine is fantastic so far, but I have one key technology I have not been able to prototype: Creating a Texture from an SDCard File.

I am trying to use an image from the SD card as a texture. I know it is not an issue with permissions, since I am able to open the file and read it via a FileInputStream object. My test file, test.png, exists both in the root of the internal storage and in the root of the SD Card. I am trying to use “application.getAssetManager().loadTexture(String filename)” to load the texture but keep getting an AssetNotFoundException. I have tried passing “test.png” as the filename, along with prefixing it with the string obtained from “Environment.getExternalStorageDirectory()” without success.

For completeness sake, here is the code I am using:

private void ModifyTexture(Geometry g)
{
	String fn = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.png";
	Texture tex = application.getAssetManager().loadTexture(fn);  // EXCEPTION THROWN HERE
	Material newmat = new Material(application.getAssetManager(),"Common/MatDefs/Misc/Unshaded.j3md");
    newmat.setTexture("ColorMap", tex);
	g.setMaterial(newmat);
}

This code works fine if I use a texture filename like “assets/Images/test.png”, but the idea is to use an image not in the apk.

Is it possible to create a texture from an image file on Android?

You’re trying to load an asset outside the default asset folder so you’ll have to register a locator first.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:faq#why_do_i_get_assetnotfoundexception_when_loading_x
(You’re looking for the FileLocator)

3 Likes

Rylius! Super thank you for the correct and swift response! You rock.

For completeness sake, here’s the correct code:

[java]
private void ModifyTexture(Geometry g)
{
application.getAssetManager().registerLocator(Environment.getExternalStorageDirectory().getAbsolutePath(), FileLocator.class);
String fn = “test.png”;
Texture tex = application.getAssetManager().loadTexture(fn);
Material newmat = new Material(application.getAssetManager(),“Common/MatDefs/Misc/Unshaded.j3md”);
newmat.setTexture(“ColorMap”, tex);
g.setMaterial(newmat);
}
[/java]

So I have one more question related to the previous question.

I’m trying to handle the case where the texture load fails, such as when the user picks a file that is not an image or if the image is too big. I surrounded the code with a try/catch, but later the GLThread crashes with an “RuntimeException”.

[java]
try
{
Texture tex = application.getAssetManager().loadTexture(fn);

				Material newmat = new Material(application.getAssetManager(),"Common/MatDefs/Misc/Unshaded.j3md");
			    newmat.setTexture("ColorMap", tex);
				g.setMaterial(newmat);
				showLogoLoadFailed = false;
			}
			catch (IllegalStateException ee)
			{
				showLogoLoadFailed = true;
			}
			catch (AssetNotFoundException e)
			{
				showLogoLoadFailed = true;
			}

[/java]
Is there a way to recover from a failed texture load?

What exaclty is the runtimeException?

My apologies. I believe the exception i was seeing was due to slow stepping through the code.

Thank you for the quick response, and a general thank you to the jME community. I really like this engine so far!

Slow stepping through the code shouldn’t cause an exception really (it never has for me).

What was the exception?

sorry for the late response. I’ve apparently fixed the issue; it was something I wasn’t doing right. thank you again for the help, and I’m digging jME! It’s a great engine for Android.