Algoritma Generasi Palet Warna



Mencari palet warna yang indah untuk situs ini? Baru-baru ini memasang lampu latar RGB di rumah, atau ingin mengecat ruangan dengan warna baru? Atau membeli keyboard dengan lampu latar warna dan ingin menggunakannya sepenuhnya? Dalam situasi apa pun Anda berada, Anda pasti akan terus menyesuaikan skema warna.

Sebagai seorang programmer, saya dengan cepat menulis beberapa baris kode untuk menghasilkan palet warna acak. Segera merasakan bahwa pendekatan seperti itu mungkin tidak memberikan hasil terbaik, dalam beberapa menit saya menerapkan tombol "reload" pada palet. Tampak bagi saya bahwa untuk mendapatkan skema yang hebat, Anda hanya perlu sedikit keberuntungan dan kesabaran.

Saya salah. Generasi palet warna acak menyebalkan. Dari waktu ke waktu, warna yang indah hidup berdampingan dengan warna coklat atau kuning yang jelek dan kotor. Koleksi warna selalu terlalu gelap, atau terlalu terang dan kontras rendah, atau set terdiri dari warna yang sangat mirip. Itu perlu untuk datang dengan solusi yang berbeda.

Ruang warna


Mari kita mulai dengan teorinya. Saat ini, ruang warna banyak digunakan untuk mengklasifikasikan warna:

sRGB


RGB adalah singkatan dari Red Green Blue . Beginilah tampilan bekerja: mereka memancarkan cahaya dalam tiga saluran warna, yang dicampur dalam proporsi berbeda untuk menghasilkan semua jenis warna. Nilai di setiap saluran bervariasi dari 0 hingga 255. R:0, G:0, B:0 (atau # 000000 dalam ekspresi heksadesimal) berwarna hitam, dan R:255, G:255, B:255 (atau #ffffff ) - putih.

Lab cie


Ruang warna CIE Lab lebih luas dari sRGB dan mencakup semua warna yang dirasakan oleh manusia. Itu dibuat dengan harapan universalitas persepsi. Dengan kata lain, jarak antara warna sesuai dengan perbedaan subyektif: jika nilai kedua warna berdekatan, maka keduanya terlihat serupa. Di sisi lain, dua warna yang berjarak satu sama lain juga dianggap sama sekali berbeda. Di CIE Lab, lebih banyak ruang yang dialokasikan untuk warna jenuh daripada untuk gelap dan terang. Ngomong-ngomong, bagi mata manusia, hijau sangat gelap hampir tidak bisa dibedakan dari hitam. Selain itu, ruang warna ini adalah tiga dimensi: L berarti cahaya (dari 0,0 hingga 1,0), a dan b (dari sekitar -1,0 hingga 1,0) adalah saluran warna.

HCL


Jika RGB menjelaskan bagaimana tampilan menampilkan warna, dan Lab CIE bagaimana kami melihatnya, maka HCL adalah ruang warna yang paling dekat menggambarkan bagaimana kami berpikir tentang warna. Ini juga tiga dimensi, H berarti hue (0 hingga 360 derajat), adalah singkatan dari chroma dan L adalah singkatan dari luminance (kedua parameter diukur dari 0,0 hingga 1,0).

Saya sarankan menggunakan CIE Lab untuk perhitungan, dan HCL untuk mewakili palet kepada pengguna. Jika diinginkan, Anda dapat mengonversi nilai dari spasi ini ke RGB.

Dekomposisi Ruang Warna


Karena saya perlu mendapatkan satu set warna unik, masing-masing, pertama-tama kita membuang warna yang terlihat sangat mirip. Ruang warna akan menjadi tiga dimensi, dan algoritma pengelompokan k-means sangat cocok untuk memisahkan set data berdimensi rendah tersebut. Dia mencoba menguraikan data (dalam kasus kami, ruang warna) menjadi k area terpisah. Dan kemudian palet disusun dari titik-titik pusat cluster di daerah ini. Gif menunjukkan tampilan dua dimensi dari algoritma dalam ruang tiga dimensi dari Lab CIE.

Menulis kode


Menggunakan metode k-means yang diterapkan pada Go, masalahnya diselesaikan hanya dalam beberapa baris kode. Pertama, siapkan nilai warna dalam ruang Lab CIE:

 var d clusters.Observations for l := 0.2; l <= 0.8; l += 0.05 { for a := -1.0; a < 1.0; a += 0.1 { for b := -1.0; b < 1.0; b += 0.1 { d = append(d, clusters.Coordinates{l, a, b}) } } } 

Saya sudah mengambil beberapa parameter dan memberlakukan batasan tertentu pada warna yang dihasilkan. Dalam contoh ini, kita akan membuang warna terlalu gelap (kecerahan <0,2) dan terlalu terang (kecerahan> 0,8).

Perluas ruang warna yang baru dibuat:

 km := kmeans.New() clusters, _ := km.Partition(d, 8) 

Fungsi Partition akan mengembalikan irisan delapan cluster. Setiap cluster memiliki titik tengah, yang merupakan warna terpisah dalam ruang yang diberikan. Koordinatnya dapat dengan mudah dikonversi ke nilai RGB heksadesimal:

 col := colorful.Lab(c.Center[0], c.Center[1], c.Center[2]) col.Clamped().Hex() 

Ingat bahwa Lab CIE lebih lebar dari RGB, yang berarti beberapa nilai Lab tidak dapat dikonversi ke RGB. Nilai-nilai ini dapat dikonversi menggunakan Clamped ke warna terdekat di ruang RGB.

Kode lengkap


 package main import ( "github.com/muesli/kmeans" "github.com/muesli/clusters" colorful "github.com/lucasb-eyer/go-colorful" ) func main() { // Create data points in the CIE L*a*b* color space // l for lightness, a & b for color channels var d clusters.Observations for l := 0.2; l <= 0.8; l += 0.05 { for a := -1.0; a <= 1.0; a += 0.1 { for b := -1.0; b <= 1.0; b += 0.1 { d = append(d, clusters.Coordinates{l, a, b}) } } } // Partition the color space into 8 clusters km := kmeans.New() clusters, _ := km.Partition(d, 8) for _, c := range clusters { col := colorful.Lab(c.Center[0], c.Center[1], c.Center[2]) fmt.Println("Color as Hex:", col.Clamped().Hex()) } } 

Seperangkat delapan (tidak begitu) warna acak yang dihasilkan oleh kode ini:



Tentukan ruang warna Anda sendiri


Tambahkan lebih banyak kontrol atas pembentukan warna. Kita dapat dengan mudah mengelola data yang digunakan untuk perhitungan lebih lanjut, dengan demikian memilih ruang warna yang sesuai dengan kebutuhan kita. Buat palet pastel:

 func pastel(c colorful.Color) bool { _, s, v := col.Hsv() return 0.2 <= s && s <= 0.4 && 0.7 <= v && v <= 1.0 } for l := 0.0; l <= 1.0; l += 0.05 { for a := -1.0; a <= 1.0; a += 0.1 { for b := -1.0; b <= 1.0; b += 0.1 { col := colorful.Lab(l, a, b) if col.IsValid() && pastel(col) { d = append(d, clusters.Coordinates{l, a, b}) } } } } 

Ruang warna lain adalah HSV , huruf dalam namanya berarti rona, saturasi dan kecerahan. Di ruang ini, warna-warna pastel biasanya memiliki kecerahan tinggi dan saturasi rendah.

Inilah yang terjadi:



Anda juga dapat memfilter warna dengan saturasi (kroma) dan kecerahannya untuk mendapatkan serangkaian nada "hangat":

 func warm(col colorful.Color) bool { _, c, l := col.Hcl() return 0.1 <= c && c <= 0.4 && 0.2 <= l && l <= 0.5 } 

Hasil:



Paket gamut


Saya sedang mengerjakan perpustakaan yang disebut gamut , yang akan mengumpulkan semua bagian yang dijelaskan di sini dalam satu paket praktis di Go, yang memungkinkan Anda untuk menghasilkan dan mengelola palet dan tema warna. Anda sudah dapat mencobanya, tetapi masih berfungsi.

Source: https://habr.com/ru/post/id414455/


All Articles