Color extraction from Vertex/UV

This tool extract color from a mesh using its uv and get its world position to emit particles

C#, Unity

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

[System.Serializable]
public struct ColorAdjustParticle
{
    [Tooltip("Object that contains particle system component")]
    public GameObject Obj;

    [Tooltip("Color value level")]
    public bool SingleColor;
}

[System.Serializable]
public struct ColorAdjustMesh
{
    [Tooltip("Object that contains particle system component")]
    public GameObject Obj;
}

[ExecuteInEditMode]
public class ParticleTextureColor : MonoBehaviour {

    [Tooltip("Reference Card Texture")]
    public Texture2D TextureImg;
    [Tooltip("Mipmap Level of the Card Texture")]
    public bool UseMipmap = false;
    [Tooltip("Mipmap Level of the Card Texture")]
    public int MipmapLevel = 0;

    [Space(10)]
    [Tooltip("Particle systems that will be affected by this color module")]
    public ColorAdjustParticle[] ParticleObjs;

    [Space(10)]
    [Tooltip("Particle systems that will be affected by this color module")]
    public ColorAdjustMesh[] MeshObjs;

    private List<Color32> MostUsedColors = new List<Color32>();

    private ParticleSystem.MainModule[] ParticleColorModules;
    private Material[] MeshMaterials;

    public Color32 C1;
    public Color32 C2;

    public float Saturation = 1.2f;
    public float Value = 2f;

    // Use this for initialization
    void Start()
    {
        //SetColors();
    }

    public void SetDominantColors(Color32 c1, Color32 c2)
    {
        C1 = c1;
        C2 = c2;
        SetColors();
    }

    void GetParticleModules()
    {
        //ParticleColorModules = new ParticleSystem.MainModule[ParticleObjs.Length];
        List<ParticleSystem.MainModule> result = new List<ParticleSystem.MainModule>();

        for (int i = 0; i < ParticleObjs.Length; i++)
        {
            GameObject obj = ParticleObjs[i].Obj;
            if (obj)
            {
                result.Add(obj.GetComponent<ParticleSystem>().main);
            }
        }

        ParticleColorModules = result.ToArray();
    }

    public void SetColors()
    {
        MeshMaterials = new Material[MeshObjs.Length];
        for (int i = 0; i < MeshObjs.Length; i++)
        {
            GameObject obj = MeshObjs[i].Obj;
            if (obj)
            {
                Renderer rend = obj.GetComponent<Renderer>();
                MeshMaterials[i] = rend.sharedMaterial;
            }
        }

        for (int i = 0; i < MeshMaterials.Length; i++)
        {
            Color adjustedC1 = SaturateAdjust(C1, Saturation, Value);

            if (MeshMaterials[i] != null)
            {
                MeshMaterials[i].SetColor("_MasterColor", adjustedC1);
            }
        }

        GetParticleModules();
        for (int i = 0; i < ParticleColorModules.Length; i++)
        {
            Color adjustedC1 = SaturateAdjust(C1, Saturation, Value);

            if (ParticleObjs[i].SingleColor)
            {
                ParticleColorModules[i].startColor = new ParticleSystem.MinMaxGradient(adjustedC1, adjustedC1); // random between 2 colors
                continue;
            }

            Color adjustedC2 = SaturateAdjust(C2, Saturation, Value);
            ParticleColorModules[i].startColor = new ParticleSystem.MinMaxGradient(adjustedC1, adjustedC2); // random between 2 colors
        } 
    }

    int DeRes(float val, int count)
    {
        int i = 0;
        while (i < count)
        {
            val *= 0.5f;
            i++;
        }
        return Mathf.RoundToInt(val);
    }

    private Color32[] GetPixels()
    {
        if (UseMipmap)
        {
            return TextureImg.GetPixels32(MipmapLevel); // at mipmap level %
        }
        else
        {
            //TextureImg.GetPixel(1, 2);
            return new Color32[10]; // TODO : return randomized picked from texture 60~100 and get 2 dominant colors - not yet ready
        }
    }

    public void GetDominantColors()
    {
        int width = TextureImg.width;
        int height = TextureImg.height;

        Color32[] Colors;
        Colors = GetPixels();

        if (MipmapLevel > 0)
        {
            width = DeRes(width, MipmapLevel + 1);
            height = DeRes(height, MipmapLevel + 1);
        }

        // does using Dictionary<Color,int> here
        // really pay-off compared to using
        // Dictionary<Color, int> ?
        // would using a SortedDictionary be much slower, or ?
        Dictionary<Color32, int> dctColorIncidence = new Dictionary<Color32, int>();
        Color32 pixelColor;
        for (int row = 0; row < width; row++)
        {
            for (int col = 0; col < height; col++)
            {
                int index = row * 10 + col;

                pixelColor = Colors[index]; // divide by 8 to cluster better
                if (pixelColor.a < 0.01f)
                    continue;

                pixelColor.r /= 8;
                pixelColor.g /= 8;
                pixelColor.b /= 8;

                if (dctColorIncidence.Keys.Contains(pixelColor))
                {
                    dctColorIncidence[pixelColor]++;
                }
                else
                {
                    dctColorIncidence.Add(pixelColor, 1);
                }
            }
        }

        // note that there are those who argue that a
        // .NET Generic Dictionary is never guaranteed
        // to be sorted by methods like this
        var dctSortedByValueHighToLow = dctColorIncidence.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);

        // this should be replaced with some elegant Linq ?
        MostUsedColors.Clear();
        foreach (KeyValuePair<Color32, int> kvp in dctSortedByValueHighToLow.Take(2))
        {
            Color32 c = kvp.Key;
            MostUsedColors.Add(c);
        }
    }

    Color32 SaturateAdjust(Color32 color, float saturation, float value)
    {
        float H;
        float S;
        float V;
        Color.RGBToHSV(color, out H, out S, out V);
        S *= saturation;
        V *= value;
        return Color.HSVToRGB(H, S, V);
    }
}