Advertisement
Flynny85

Simple palette capture from image in unity

Jul 6th, 2017
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.69 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System;
  5.  
  6. #if UNITY_EDITOR
  7. using UnityEditor;
  8. [CustomEditor(typeof(Palette_Tool))]
  9. public class Palette_ToolOverride : Editor
  10. {
  11.  
  12.  
  13.     public override void OnInspectorGUI()
  14.     {
  15.         Palette_Tool _temp = (Palette_Tool)target;
  16.         if(GUILayout.Button("Use image for palette"))
  17.         {
  18.             _temp.debugColourQuant();
  19.         }
  20.         DrawDefaultInspector();
  21.     }
  22. }
  23. #endif
  24.  
  25. [Serializable]
  26. public class Palette_Class {
  27.     public int _palette_ID;
  28.     public string _palette_Name;
  29.     public Color _palette_Dominant;
  30.     public Gradient _palette_Subs;
  31. }
  32.  
  33. [Serializable]
  34. public struct Palette_Struct {
  35.     public Color32 _colour_RGB;
  36.     public float h, s, v;
  37.     public int _count;
  38.     public float _lum;
  39.  
  40.     public Palette_Struct( Color color , int count ){
  41.         this._colour_RGB = color;
  42.         Color.RGBToHSV ( this._colour_RGB , out this.h , out this.s , out this.v );
  43.         this._count = count;
  44.         this._lum = ((0.375f * this._colour_RGB.r)/255) + ((0.5f * this._colour_RGB.g)/255) + ((0.125f * this._colour_RGB.b)/255);
  45.         return;
  46.     }
  47.     public void Set_Colour( Color32 _newColour ){
  48.         this._colour_RGB = _newColour;
  49.         Color.RGBToHSV ( this._colour_RGB , out this.h , out this.s , out this.v );
  50.         this._lum = ((0.375f * this._colour_RGB.r)/255) + ((0.5f * this._colour_RGB.g)/255) + ((0.125f * this._colour_RGB.b)/255);
  51.     }
  52. }
  53.  
  54. public class PaletteSpaceCount: IComparer<Palette_Struct>
  55. {
  56.     public int Compare(Palette_Struct x, Palette_Struct y)
  57.     {
  58.         int retval = y._count.CompareTo(x._count);
  59.         return retval;
  60.     }
  61. }
  62. public class PaletteSpaceHue: IComparer<Palette_Struct>
  63. {
  64.     public int Compare(Palette_Struct x, Palette_Struct y)
  65.     {
  66.         float xHue = x.h;
  67.         float yHue = y.h;
  68.         int retval = 0;
  69.         if( xHue < yHue){
  70.             retval = 1;
  71.         } else if ( xHue > yHue ){
  72.             retval = -1;
  73.         }
  74.         return retval;
  75.     }
  76. }
  77. public class PaletteSpaceVal: IComparer<Palette_Struct>
  78. {
  79.     public int Compare(Palette_Struct x, Palette_Struct y)
  80.     {
  81.         int retval = (y._lum) .CompareTo( (x._lum) );
  82.         return retval;
  83.     }
  84. }
  85.  
  86. public class Palette_Tool : MonoBehaviour {
  87.  
  88.     public int Quality = 4; // every so many pixels sample ..
  89.     private int Quality_i; // every so many pixels sample ..
  90.     public Texture2D Image;
  91.  
  92.     public void debugColourQuant(){
  93.         ColourQuantize ( Image );
  94.     }
  95.  
  96.     private Dictionary<int,int> _palettDict = new Dictionary<int, int>();
  97.     private List<Color32> _paletteColours = new List<Color32> ();
  98.  
  99.     private List<float> _hueCutOffs = new List<float> ();
  100.     private List<Palette_Struct> _currentHues = new List<Palette_Struct> ();
  101.  
  102.     private List<Palette_Struct> _palette_List_All = new List<Palette_Struct> ();
  103.     private List<Palette_Struct> _palette_List = new List<Palette_Struct> ();
  104.     private List<Palette_Struct> _palette_Clean_List = new List<Palette_Struct> ();
  105.  
  106.     PaletteSpaceCount _paletteSortCount = new PaletteSpaceCount();
  107.     PaletteSpaceHue _paletteSortHue = new PaletteSpaceHue();
  108.     PaletteSpaceVal _paletteSortVal = new PaletteSpaceVal();
  109.     private int _colourHash = 0;
  110.     private int _Size;
  111.     private int _Count;
  112.     private int _Count02;
  113.     private int _CountHue;
  114.     private int _intVal;
  115.  
  116.  
  117.     private const float Hue_Sensitivity = 0.005f;
  118.     private const float _darkestValAllowed = 0.25f;
  119.     private const float _lightestValAllowed = 0.98f;
  120.  
  121.     private Palette_Struct _tempColour;
  122.     private float _Avg_Hue;
  123.     private float _Avg_Lum;
  124.     private float _Avg_Sat;
  125.     private int _Avg_Count;
  126.     private int _Hi_Count;
  127.     private float _power;
  128.     public int _paletteSizeMax = 10;
  129.     public List<Color> _palette_Slots = new List<Color> ();
  130.  
  131.     private void Add_NewHueCutOff( float _val ){
  132.         if (_hueCutOffs.Contains (_val) == false) {
  133.             _hueCutOffs.Add (_val);
  134.         }
  135.     }
  136.  
  137.     public void ColourQuantize( Texture2D tex ){
  138.         // clear arrays //
  139.         _palettDict.Clear (); _palette_List_All.Clear ();  _palette_Clean_List.Clear();
  140.         _palette_Slots.Clear (); _paletteColours.Clear ();
  141.         _hueCutOffs.Clear ();
  142.  
  143.         Quality = Mathf.Clamp( Quality , 1, 9);
  144.         Quality_i = 10 - Quality;
  145. //      Hue_Sensitivity = Mathf.Clamp ( Hue_Sensitivity , 0f , 1f);
  146.  
  147.  
  148.         Color32[] texColors = tex.GetPixels32();
  149.         _Size = texColors.Length;
  150.  
  151.         for (_Count = 0; _Count < _Size; _Count += Quality_i) {
  152.             _colourHash = ColorUtility.ToHtmlStringRGB( texColors [_Count] ).GetHashCode() ;
  153.             _intVal = 0;
  154.             if ( _palettDict .TryGetValue( _colourHash , out _intVal)) {
  155.                 _palettDict[ _colourHash ] +=1;
  156.             } else {
  157.                 _palettDict.Add ( _colourHash , 1);
  158.                 _paletteColours.Add ( texColors [_Count] );
  159.             }
  160.         }
  161.  
  162.         for (_Count = 0; _Count < _paletteColours.Count; _Count ++) {
  163.             _colourHash = ColorUtility.ToHtmlStringRGB( _paletteColours [_Count] ).GetHashCode() ;
  164.             _intVal = _palettDict [_colourHash];
  165.             if ( _intVal > 1 ) {
  166.                 _tempColour = new Palette_Struct ( _paletteColours [_Count] , _intVal );
  167.                 if( _tempColour._lum < _lightestValAllowed && _tempColour._lum > _darkestValAllowed ){
  168.                     if (_tempColour.s > .1f ) {
  169.                         _palette_List_All.Add (_tempColour);
  170.                     }
  171.                 }
  172.             }
  173.         }
  174.  
  175.         _palette_List_All.Sort ( _paletteSortHue );
  176.  
  177.         // find hue cutoffs .. RANGES //
  178.         Add_NewHueCutOff ( 1f );
  179.         for (_Count = 0; _Count < _palette_List_All.Count - 1; _Count++) {
  180.             if( _palette_List_All[_Count].h - _palette_List_All[_Count + 1].h > Hue_Sensitivity ){
  181.                 if (_hueCutOffs.Count % 2 == 0) {
  182.                     Add_NewHueCutOff(_palette_List_All [_Count].h);
  183.                 } else {
  184.                     Add_NewHueCutOff ( _palette_List_All[_Count + 1].h );
  185.                 }
  186.             }
  187.         }
  188.         Add_NewHueCutOff ( 0f);
  189.  
  190.         _Size = _hueCutOffs.Count - 1;
  191.         for (_CountHue = 0; _CountHue < _Size; _CountHue++) {
  192.             _currentHues.Clear ();
  193.             _Avg_Hue = 0f; _Avg_Sat = 0f; _Avg_Lum = 0f; _Hi_Count = 0;
  194.             for (_Count = 0; _Count < _palette_List_All.Count; _Count++) {
  195.                 if( _palette_List_All[_Count].h < _hueCutOffs[_CountHue] && _palette_List_All[_Count].h > _hueCutOffs[_CountHue + 1]){
  196.                     _currentHues.Add ( _palette_List_All[_Count] );
  197.                     _Hi_Count = Mathf.Max ( _Hi_Count , _palette_List_All [_Count]._count );
  198.                 }
  199.             }
  200.  
  201.             //sort by strength!
  202.             _currentHues.Sort ( _paletteSortVal );
  203.  
  204.             // find strength cutoff!
  205.             _intVal = 0;
  206.  
  207.             if (_currentHues.Count > 0) {
  208.  
  209.                 for (_Count = 0; _Count < _currentHues.Count; _Count++) {
  210.                     _Avg_Hue += _currentHues [_Count].h;
  211.                     _Avg_Sat += _currentHues [_Count].s;
  212.                     _Avg_Lum += _currentHues [_Count].v;
  213.                     // avg above gets more brighter colours instead ...
  214. //                  _power = Mathf.Max( 0.1f , (float)_currentHues [_Count]._count / _Hi_Count );
  215. //                  _Avg_Hue = Mathf.Lerp( _Avg_Hue , _currentHues [_Count].h , _power );
  216. //                  _Avg_Lum = Mathf.Lerp( _Avg_Lum , _currentHues [_Count].v , _power );
  217. //                  _Avg_Sat = Mathf.Lerp( _Avg_Sat , _currentHues [_Count].s , _power );
  218.                     _intVal += _currentHues [_Count]._count;
  219.                 }
  220.  
  221.                 _Count02 = _currentHues.Count + 1;
  222.  
  223.                 _Avg_Hue = _Avg_Hue / _Count02;
  224.                 _Avg_Sat = _Avg_Sat / _Count02;
  225.                 _Avg_Lum = _Avg_Lum / _Count02;
  226.  
  227.                 _palette_Clean_List.Add (new Palette_Struct (Color.HSVToRGB (_Avg_Hue, _Avg_Sat, _Avg_Lum), _intVal));
  228.             }
  229.         }
  230.  
  231.         _palette_Clean_List.Sort ( _paletteSortVal );
  232.  
  233. //      // softening palette // is pretty meh ..
  234. //      for (_Count = 0; _Count < _palette_Clean_List.Count; _Count++) {
  235. //          if (_Count < _palette_Clean_List.Count / 2 - 1) {
  236. //              _tempColour = _palette_Clean_List [_Count];
  237. //              _tempColour._colour_RGB = Color.Lerp ( _tempColour._colour_RGB , Color.white , .05f );
  238. //              _palette_Clean_List [_Count] = _tempColour;
  239. //          } else {
  240. //              if (_Count > _palette_Clean_List.Count / 2 + 1) {
  241. //                  _tempColour = _palette_Clean_List [_Count];
  242. //                  _tempColour._colour_RGB = Color.Lerp (_tempColour._colour_RGB, Color.black, .05f );
  243. //                  _palette_Clean_List [_Count] = _tempColour;
  244. //              }
  245. //          }
  246. //      }
  247.  
  248.         // search final list for simialar colour!
  249.         for (_Count = 0; _Count < _palette_Clean_List.Count; _Count++) {
  250.             // get all closest colours to this one!
  251.             for (_Count02 = 0; _Count02 < _palette_Clean_List.Count; _Count02++) {
  252.                 if (_Count != _Count02) {
  253.                     if ( _palette_Clean_List [_Count]._count > 1 && _palette_Clean_List [_Count02]._count > 1 ) {
  254.                         if ( Mathf.Abs( _palette_Clean_List [_Count].h - _palette_Clean_List [_Count02].h) < .04f) {
  255.                             if ( Mathf.Abs( _palette_Clean_List [_Count]._lum - _palette_Clean_List [_Count02]._lum) < .1f) {
  256.                                 if (_palette_Clean_List [_Count]._lum > _palette_Clean_List [_Count02]._lum) {
  257.                                     _tempColour._colour_RGB = Color.red;
  258.                                     _Avg_Count = _palette_Clean_List [_Count02]._count;
  259.                                     _tempColour._count = -1;
  260.                                     _palette_Clean_List [_Count02] = _tempColour;
  261.                                     _tempColour = _palette_Clean_List [_Count];
  262.                                     _tempColour._count += _Avg_Count;
  263.                                     _palette_Clean_List [_Count] = _tempColour;
  264.                                 } else {
  265.                                     _tempColour._colour_RGB = Color.red;
  266.                                     _Avg_Count = _palette_Clean_List [_Count]._count;
  267.                                     _tempColour._count = -1;
  268.                                     _palette_Clean_List [_Count] = _tempColour;
  269.                                     _tempColour = _palette_Clean_List [_Count02];
  270.                                     _tempColour._count += _Avg_Count;
  271.                                     _palette_Clean_List [_Count02] = _tempColour;
  272.                                 }
  273.                             }
  274.                         }
  275.                     }
  276.                 }
  277.             }
  278.         }
  279.  
  280.  
  281.         _palette_Clean_List.Sort ( _paletteSortCount );
  282.         _palette_Slots.Add ( _palette_Clean_List[0]._colour_RGB );
  283.         _palette_Clean_List.RemoveAt (0);
  284.  
  285.  
  286.  
  287.         for (_Count = _palette_Clean_List.Count - 1; _Count > 0; _Count--) {
  288.             if ( _Count > _paletteSizeMax) {
  289.                 _palette_Clean_List.RemoveAt( _Count );
  290.             }
  291.         }
  292.  
  293.         _palette_Clean_List.Sort ( _paletteSortVal );
  294.  
  295.         for (_Count = 0; _Count < Mathf.Min( _paletteSizeMax , _palette_Clean_List.Count ); _Count++) {
  296.             if (_palette_Clean_List [_Count]._count > 1) {
  297.                 _palette_Slots.Add (_palette_Clean_List [_Count]._colour_RGB);
  298.             }
  299.         }
  300.  
  301.     }
  302.  
  303.  
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement