Page 1 of 1

Problems with images

Posted: 10 Mar 2015, 09:33
by markg
1. If I try to use a PNG image in my project I receive the following error:
[gl] Assets/GUI/Common/Workflow/Resources/senil_prepare.png
Image format not supported

UnityEngine.Debug:LogError(Object)
Noesis.BuildToolKernel:OnLog(Int32, String) (at Assets/Editor/NoesisGUI/NoesisBuildToolKernel.cs:260)
System.Object:wrapper_native_0x36d1a3f0(String)
Noesis.BuildToolKernel:BuildIncremental() (at Assets/Editor/NoesisGUI/NoesisBuildToolKernel.cs:116)
NoesisPostProcessor:Build(String) (at Assets/Editor/NoesisGUI/NoesisPostProcessor.cs:248)
NoesisPostProcessor:Build() (at Assets/Editor/NoesisGUI/NoesisPostProcessor.cs:234)
NoesisPostProcessor:OnPostprocessAllAssets(String[], String[], String[], String[]) (at Assets/Editor/NoesisGUI/NoesisPostProcessor.cs:172)
UnityEditor.AssetPostprocessingInternal:PostprocessAllAssets(String[], String[], String[], String[], String[])
2. If I convert the image to JPG then it works.
3. If I hardcode the path to the JPG image in XAML then it loads properly:
<Image Source="Resources/senil_prepare.jpg" Canvas.Top="45" Canvas.Left="115"/>
4. If I use binding instead with the exact same path specified in code-behind then it doesn't work:
<Image Source="{Binding Icon}"/>
Exception: Resource Resources/senil_prepare.jpg not found
Noesis.Error.Check () (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisError.cs:21)
Noesis.UIRenderer.Noesis_CreateRenderer (IntPtr root) (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisUIRendererImports.cs:87)
Noesis.UIRenderer..ctor (Noesis.FrameworkElement content, Vector2 offscreenSize, UnityEngine.GameObject target) (at Assets/Plugins/NoesisGUI/Scripts/Core/NoesisUIRenderer.cs:61)
NoesisGUIPanel.OnEnable () (at Assets/Plugins/NoesisGUI/Scripts/NoesisGUIPanel.cs:172)

Re: Problems with images

Posted: 10 Mar 2015, 20:55
by sfernandez
1 & 2. Which .png format are you using? Maybe it is a 16-bit per channel image that we don't support. Common pngs are imported fine.

3. Paths in a .xaml file can be specified as relative to the xaml file or absolute as explained here. When xaml file is processed by our resource builder, it transforms the relative and absolute URIs to NoesisGUI resource paths (in Unity that means paths relative to the Unity project directory). As you can see in the error output, the image path "Resources/senil_prepare.png" is converted to "Assets/GUI/Common/Workflow/Resources/senil_prepare.png".

In fact, Image.Source property's type is an ImageSource object (not a string), and when xaml is processed the URI is automatically converted to an ImageSource.

4. So when using a binding, the runtime code expects to receive an ImageSource object for the Image.Source property. You can create a TextureSource from a Unity Texture object as explained at the bottom of Images tutorial. For example:
public class Item
{
  public Noesis.ImageSource Icon { get; set; }
}
...

ViewModel vm = new ViewModel();
vm.Items.Add(new Item { Icon = new TextureSource(Resources.Load("senil_prepare") as Texture) });
Another option is to expose the URI as a string in the ViewModel and use a converter that knows how to provide a valid ImageSource in runtime:
public class UriToImageSourceConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    UnityEngine.Texture tex = UnityEngine.Resources.Load((string)value) as UnityEngine.Texture;
    if (tex == null)
      return null;
    return new TextureSource(tex);
  }
  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    throw new NotSupportedException("Not implemented");
  }
}

public class Item
{
  public string Icon { get; set; }
}
...

ViewModel vm = new ViewModel();
vm.Items.Add(new Item { Icon = "senil_preparing" });
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid.Resources>
    <UriToImageSourceConverter x:Key="uriConverter"/>
  </Grid.Resources>
  ...
  <Image Source="{Binding Icon, Converter={StaticResource uriConverter}}"/>
  ...
</Grid> 
If you don't understand anything don't hesitate to ask again :)