This Has Me Stumped... Failing to Load PNG on Droid 4.1.1

This one has me a little stumped! I have 1 texture in my project which fails to load. I am using Monogame 3.2 and the XNA content pipeline. This issue only started happening when I ran my game on a Motorola Droid Razr (Android 4.1.1) emulator. It runs fine on a Galaxy S4 (Android 4.4) emulator.

I get the usual content error:

Microsoft.Xna.Framework.Content.ContentLoadException: Could not load Sprites\UI\InGame\winner01_black asset as a non-content file! ---> System.Exception: Opening stream error. ---> System.Exception: 
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0
  at Android.Runtime.JNIEnv.CallIntMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00064] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:369
  at Java.IO.InputStream.Read (System.Byte[] buffer, Int32 offset, Int32 length) [0x0004a] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/platforms/android-15/src/generated/Java.IO.InputStream.cs:274
  at Android.Runtime.InputStreamInvoker.Read (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/src/Runtime/InputStreamInvoker.cs:30
  at System.IO.Stream.CopyTo (System.IO.Stream destination, Int32 bufferSize) [0x00000] in <filename unknown>:0
  at System.IO.Stream.CopyTo (System.IO.Stream destination) [0x00000] in <filename unknown>:0
  at Microsoft.Xna.Framework.Content.ContentManager.OpenStream (System.String assetName) [0x00024] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Content\ContentManager.cs:251
  at --- End of managed exception stack trace ---
  at at android.content.res.AssetManager.readAsset(Native Method)
  at at android.content.res.AssetManager.access$700(
  at at android.content.res.AssetManager$
  at at Method)
  at at
  at at android.os.Handler.handleCallback(
  at at android.os.Handler.dispatchMessage(
  at at android.os.Looper.loop(
  at at
  at at java.lang.reflect.Method.invokeNative(Native Method)
  at at java.lang.reflect.Method.invoke(
  at at$
  at at
  at at dalvik.system.NativeStart.main(Native Method)
  --- End of inner exception stack trace ---
  at Microsoft.Xna.Framework.Content.ContentManager.OpenStream (System.String assetName) [0x0005d] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Content\ContentManager.cs:269
  at Microsoft.Xna.Framework.Content.ContentManager.ReadAsset[Texture2D] (System.String assetName, System.Action`1 recordDisposableObject) [0x00067] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Content\ContentManager.cs:301
  --- End of inner exception stack trace ---
  at at Microsoft.Xna.Framework.Content.ContentManager.ReadAsset<Microsoft.Xna.Framework.Graphics.Texture2D> (string,System.Action`1<System.IDisposable>) <0x0078f>
  at at Microsoft.Xna.Framework.Content.ContentManager.Load<Microsoft.Xna.Framework.Graphics.Texture2D> (string) <0x001e3>
  at MBHEngine.Behaviour.SpriteRender.LoadTexture (string) [0x00035] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\Behaviour\SpriteRender.cs:525
  at MBHEngine.Behaviour.SpriteRender.LoadContent (string) [0x00030] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\Behaviour\SpriteRender.cs:419
  at MBHEngine.Behaviour.Behaviour..ctor (MBHEngine.GameObject.GameObject,string) [0x0000f] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\Behaviour\Behaviour.cs:53
  at MBHEngine.Behaviour.SpriteRender..ctor (MBHEngine.GameObject.GameObject,string) [0x00000] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\Behaviour\SpriteRender.cs:402
  at MBHEngine.GameObject.GameObject.CreateBehaviourByName (string,string) [0x001b0] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\GameObject\GameObject.cs:530
  at MBHEngine.GameObject.GameObject.LoadContent (string) [0x00189] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\GameObject\GameObject.cs:222
  at MBHEngine.GameObject.GameObject..ctor (string) [0x0005d] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\GameObject\GameObject.cs:168
  at MBHEngine.GameObject.GameObjectFactory.AddTemplate (string,int) [0x0002c] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\GameObject\GameObjectFactory.cs:113
  at Roses.RosesGame.LoadContent () [0x00cfa] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\Roses\RosesGame.cs:162
  at Microsoft.Xna.Framework.Game.Initialize () [0x00047] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Game.cs:577
  at MBHEngine.Game.Initialize () [0x000ab] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\MBHEngine\Code\Game\Game.cs:187
  at Roses.RosesGame.Initialize () [0x00022] in c:\Users\Matt\Documents\Dev\Game\mbhwarofroses\Roses\Roses\RosesGame.cs:56
  at Microsoft.Xna.Framework.Game.DoInitialize () [0x00011] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Game.cs:707
  at Microsoft.Xna.Framework.AndroidGamePlatform.BeforeUpdate (Microsoft.Xna.Framework.GameTime) [0x00008] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Android\AndroidGamePlatform.cs:67
  at Microsoft.Xna.Framework.Game.DoUpdate (Microsoft.Xna.Framework.GameTime) [0x00006] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Game.cs:679
  at Microsoft.Xna.Framework.Game.Tick () [0x001d2] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Game.cs:528
  at Microsoft.Xna.Framework.AndroidGameWindow.OnUpdateFrame (object,OpenTK.FrameEventArgs) [0x00053] in c:\Users\Matt\Documents\Dev\Game\MonoGame_3_2\MonoGame.Framework\Android\AndroidGameWindow.cs:90
  at OpenTK.GameViewBase.OnUpdateFrame (OpenTK.FrameEventArgs) [0x00014] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/OpenGLES/Android/GameViewBase.cs:312
  at OpenTK.Platform.Android.AndroidGameView.UpdateFrameInternal (OpenTK.FrameEventArgs) [0x00013] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/OpenGLES/Android/AndroidGameView.cs:338
  at OpenTK.Platform.Android.AndroidGameView.RunIteration (System.Threading.CancellationToken) [0x00096] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/OpenGLES/Android/AndroidGameView.cs:523
  at OpenTK.Platform.Android.AndroidGameView/<StartThread>c__AnonStorey0.<>m__0 (object) [0x0000d] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/OpenGLES/Android/AndroidGameView.cs:431
  at Android.App.SyncContext/<Send>c__AnonStorey1.<>m__0 () [0x00000] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/src/Android.App/SyncContext.cs:32
  at Java.Lang.Thread/RunnableImplementor.Run () [0x0000b] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:36
  at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) [0x00009] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/platforms/android-15/src/generated/Java.Lang.IRunnable.cs:71
  at at (wrapper dynamic-method) object.0770ba55-370c-4cc1-8319-756d9ee16385 (intptr,intptr) <IL 0x00011, 0x0001b>

Ever other texture in the game loads fine, so I assumed I did something silly with this particular texture but things got really weird as I tried to narrow it down.

First, I tried overwriting that texture file with one I know works, and it loaded fine.

I then tried just opening up the broken texture in Gimp and re-saving it (in case I had some bad settings or something), and it still failed to load.

I then tried copying and pasting the image data in that texture to a whole new file, saved that new file, and that new texture fails too! Starting to get weird…

I then made some arbitrary changes to the texture (drawing lines all over it) re-saved and now it loads! Very weird!

Just to confirm, I undid those arbitrary changes, re-saved the texture again, and it fails to load again.

I then made some really minor changes to the texture (adding a single red pixel) and that still fails to load. So it seems to require a “significant” (what ever that is) change to fix the loading issue.

I have put the two versions of the PNG (and resulting XNB) here hoping that someone might be able to tell me what would cause one to fail to load and the other work!

Microsoft.Xna.Framework.Content.ContentLoadException: Could not load Sprites\UI\InGame\winner01_black asset as a non-content file!

Well the error says enought, the picture inside the content folder isn’t marked as a content and the content pipeline can’t find it.

Android uses a case-sensitive file system. Is the case of the entire path and filename correct?

The place it is throwing the exception is where it copies the xnb file to a MemoryStream. At this point it is just a file that is being copied to a memory buffer.

The content pipeline finds and builds an XNB. Check the link at the bottom of my post; they are in there.

As I mentioned (but maybe a little confusing), i replaced the image in that png (put another image file with the same name, at its location; overwriting it) and it worked (without changing any content or build settings). Also the version that fails on android 4.1 works fine on android 4.4.

“Android uses a case-sensitive file system. Is the case of the entire path and filename correct?”

Yes i am confident the path is correct as I did a test where i just saved another file in it’s place and everything worked (without any change to game or content pipeline).

Sounds like it’s being saved as an 8-bit palettised PNG. I think some programs will do this automatically for you if they detect greyscale images with 256 or less colours - possibly this is what Gimp is doing? The fact that it works after you put colour in it leads me to think this. If you try Paint.NET, it has options when saving as PNG for 8, 24 or 32 bits per pixel.

Thanks for the idea @Aranda, but I exported from as a 32 bit png and still have the issue. :frowning:

I just tried saving that broken PNG out as a TGA to see if that makes a difference, and it did not (it is still broken). So I suspect it is something in the content pipeline altering the image in some way (perhaps turning it into a palettised lookup as @Aranda suggested might have been happening at a higher level).

The best suggestion I have at this point is to debug through the content loading code to see where the first exception is happening. Definitely seems like some obscure issue with texture formats or something. Is the XNB compiled with vanilla XNA content pipeline, or MonoGame’s content pipeline?

XNA Content Pipeline, @Aranda.

I found a workable solution for me. I reduced the problem image from 512x256 to 512x128 pixels. How or why that fixes the issue… I have no clue. This change simply removes about 120 pixels of empty space from the texture (I had to clip a few used pixels to fit in 128 but at this point I just need something that works).

Thanks for all the other ideas guys!