NPBruce / valkyrie

Valkyrie GM for Fantasy Flight Board Games
Apache License 2.0
506 stars 105 forks source link

Mom: Import all the images #730

Open redwolf2 opened 6 years ago

redwolf2 commented 6 years ago

images

There are alot of images in the level assets,. I'm working on it.

NPBruce commented 6 years ago

It looks like this system is used more heavily for IA also. I have done the main import but there isn't much audio, and interestingly I can't find a font.

redwolf2 commented 6 years ago

Bitmap Fonts?

redwolf2 commented 6 years ago

This was a first step to it https://github.com/NPBruce/valkyrie/issues/730

Our problem for now: What if an image is renamed or the import order changes. This would lead to a lot of manual labor and troubleshooting in order to load the right images again.

To make it work in general, we could implement some sort of perceptual image hashing. In order to do this, the import has to generate an ini with all textures to parse. This ini would then be read in the render thread of the application (Texture2D can only be manipulated at runtime) and generate a second ini, containing the a table of hashes to image files. Instead of a file name, we can provide a hash, to the file, that can be resolved via the hash table.

This is just non tested Pseudocode but we could populate a list of hashes for every texture (in a new ini file). On demand, we could provide the fingerprint instead of the image. In that case the image would be looked up in the file with all the fingerprints.

// https://jenssegers.com/61/perceptual-image-hashes
public static string CreateFingerPrint(UnityEngine.Texture2D texture)
{
    // Clone texture and scale it to a 8x8 image
    UnityEngine.Texture2D clone = new UnityEngine.Texture2D(texture.width, texture.height);
    UnityEngine.Graphics.CopyTexture(texture, clone);
    clone.Resize(8, 8, UnityEngine.TextureFormat.ETC2_RGBA8, false);
    clone.Apply();
    // Convert all colors to grey
    UnityEngine.Color[] pixels = clone.GetPixels();
    var fingerPrint = new List<byte>();
    pixels.ToList().ForEach(x => fingerPrint.Add((byte)(pixels[0].grayscale * 255f)));
    // we end up with 64 bytes of fingerprint
    return Convert.ToBase64String(fingerPrint.ToArray());
}

public static bool MatchesFingerprint(string a, string b)
{
    byte[] ab = Convert.FromBase64String(a);
    byte[] bb = Convert.FromBase64String(b);
    if (ab.Length != bb.Length) return false;
    if (ab.Equals(bb)) return true;
    var matches = new List<bool>();
    for (int i = 0; i < ab.Length; i++)
    {
        int allowedDifference = 10;
        matches.Add(Math.Abs(ab[i] - bb[i]) <= allowedDifference); // 10 shades of gray difference allowed here
    }
    return matches.Where(x => x == true).Count() > 5; // allow 5 pixel to be off
}

I don't know when and if I find the time to implement it, so if anyone want to go down this road feel free to do it.

slycozzolino commented 6 years ago

Your fix may already resolve this but I wanted to just add another instance of the image not loading properly. It should be all symbols and no numbers. image

redwolf2 commented 6 years ago

@slycozzolino Did that happen on Android or on your Windows version?

slycozzolino commented 6 years ago

Windows

NPBruce commented 6 years ago

That is a different issue, I have raised #767 .

scrubbless commented 6 years ago

Are there plans to add images/textures to the other puzzles aswell?

They are perfectly functional (as is the code puzzle) but having a bit more texture would help with immersion as it does in the official app.

redwolf2 commented 6 years ago

@scrubbless yes, the request is here: https://github.com/NPBruce/valkyrie/issues/354

scrubbless commented 6 years ago

Thanks redwolf!