What's the best way to incorporate dynamically loaded textures into GUI controls?

I’d like to load in rectangular image resources via script, and use those images on GUI controls (i.e. drawn via OnGUI.) The problem I’ve run into is that when the pixel dimensions of the images I’m using aren’t both powers of two, Unity scales them using the wrong aspect ratio (probably the powers-of-two aspect ratio of the enclosing Texture2D.)

The best workaround I’ve found so far is to use GUI.DrawTexture to draw an image on top of a control (e.g. a button), and specifying the aspect ratio that I know to be correct based on the pixel dimension. But this presumes I always know the actual pixel size of the source, which may not always be the case.

I’ve also tried the following:

  • Using a GUITexture and PixelInset to prevent scaling. But I can’t figure out how to manage Z-order to make sure that a particular GUITexture will always draw on top of an OnGUI control. No matter what combination I use for the transform Z position on the GUITexture and GUI.depth in the OnGUI call, the OnGUI controls always render in front of the GUITexture.
  • If the image were in my project’s asset db, I could mark it as TextureImporterType.GUI. But I need to support images that I won’t know about at compile time, and Resources.Load doesn’t seem to support anything analogous (and I don’t see any properties on Texture2D that I can set after loading the image to get that behavior.)

Is there a better way to approach this than using GUI.DrawTexture with a specified aspect ratio? If not, is there a way for me to get the real pixel dimensions of the JPG/PNG that I’m loading into a Texture2D so that I can guarantee that my aspect ratio matches this?

You’re going to need to use a C#/Mono library to load the jpeg/png yourself. That will give you the real dimensions, and also raw pixels that you can copy into Texture2D. There are a lot of libraries that will read standard image formats, just google a bit and you’ll probably find one that works for you.