Palette API นั้นเป็น API ที่ทาง Google ได้ปล่อยออกมาเพื่อรองรับกับ Material Design และได้ทำเป็น AndroidX Library เพื่อให้สามารถใช้งานกับแอนดรอยด์เวอร์ชันเก่าๆได้ด้วย จึงขอหยิบมาพูดถึงซักหน่อย

โดย Palette API จะทำการแยกสีของภาพนั้นๆออกมาเพื่อบอกว่าภาพนั้นๆมีสีเป็นโทนอะไรบ้าง เพื่อให้นักพัฒนาสามารถนำสีดังกล่าวไปใช้กับ UI ในส่วนอื่นๆเพื่อให้เหมาะสมกับภาพนั้นๆ

จากภาพข้างบนนี้จะเห็นว่าในแต่ละเพลงนั้นจะมีปกเพลงแตกต่างกันไป และรายละเอียดเกี่ยวกับเพลงนั้นๆก็จะมีสีพื้นหลังที่แตกต่างกันไปตามสีบนปกเพลงด้วย

การทำแบบนี้ได้ก็มาจากการคำนวนค่าสีที่อยู่บนภาพนั่นแหละ ซึ่ง Palette API จะดึงสีจากภาพอยู่ 2 แบบด้วยกันคือ Vibrant (สีสด) และ Muted (สีหม่น) แถมยังแยกตามความสว่างของสีแต่ละแบบให้อีกด้วย โดยแบ่งเป็น Light, Normal และ Dark

อะไรนะ ไม่ค่อยเข้าใจ? ถ้างั้นดูภาพตัวอย่างข้างล่างนี้เลยดีกว่า

จากภาพข้างบนนี้ เจ้าของบล็อกแล้วลองใช้ Palette API ในการดึงค่าสีของภาพแล้วนำมาแสดงผลเพื่อให้เห็นว่าสีแต่ละโทนแต่ละแบบจะแตกต่างกันยังไง ซึ่งจะได้ออกมาทั้งหมด 6 โทนสี

  • Light Vibrant : สีสดออกสว่าง
  • Vibrant : สีสดปานกลาง
  • Dark Vibrant : สีสดออกมืด
  • Light Muted : สีหม่นออกสว่าง
  • Muted : สีหม่นปานกลาง
  • Dark Muted : สีหมดออกมืด

และในกรณีที่หาค่าสีในบางช่วงไม่เจอ ก็สามารถกำหนดสี Default ได้ว่าจะให้เป็นสีอะไรแทนที่ ยกตัวอย่างเช่น สีขาว เป็นต้น

การเรียกใช้งาน Palette API

เริ่มจากเพิ่ม Dependency ของ Palette API เข้าไปใน build.gradle แบบนี้

// Java
implementation 'androidx.palette.palette:1.0.0'

// Kotlin
implementation 'androidx.palette:palette-ktx:1.0.0'

เวลาที่จะเรียกใช้งาน ให้เรียกผ่านคลาสที่ชื่อว่า Palette ซึ่งจะมีคำสั่ง from(bitmap: Bitmap) แล้วกำหนด Bitmap ที่ต้องการลงไป

val bitmap: Bitmap = /* ... */

// Synchronous
val palette: Palette = Palette.from(bitmap).generate()

// Asynchronous
Palette.from(bitmap).generate { palette: Palette? ->
    // Do something
}

จะเห็นว่าคำสั่ง generate(...) นั้นมี 2 แบบด้วยกันคือ Synchronous กับ Asycnhronous ซึ่งเจ้าของบล็อกแนะนำให้ใช้แบบ Asynchronous มากกว่า จะได้ไม่ Block UI Thread

เมื่อได้ค่าออกมาเป็น Palette ก็ให้ใช้คำสั่งต่างๆเพื่อดึงค่าสีออกมาได้เลย

val palette: Palette = /* ... */
val defaultColor = Color.WHITE
val lightVibrantColor: Int = palette.getLightVibrantColor(defaultColor)
val vibrantColor: Int = palette.getVibrantColor(defaultColor)
val darkVibrantColor: Int = palette.getDarkVibrantColor(defaultColor)
val lightMutedColor: Int = palette.getLightMutedColor(defaultColor)
val mutedColor: Int = palette.getMutedColor(defaultColor)
val darkMutedColor: Int = palette.getDarkMutedColor(defaultColor)

นอกจากจะดึงค่าสีแต่ละแบบใน Palette ได้แล้ว ยังสามารถดึงค่า Swatch ของแต่ละสีออกมาใช้งานได้อีกด้วย

val palette: Palette = /* ... */
val lightVibrantSwatch: Palette.Swatch? = palette.lightVibrantSwatch
val vibrantSwatch: Palette.Swatch? = palette.vibrantSwatch
val darkVibrantSwatch: Palette.Swatch? = palette.darkVibrantSwatch
val lightMutedSwatch: Palette.Swatch? = palette.lightMutedSwatch
val mutedSwatch: Palette.Swatch? = palette.mutedSwatch
val darkMutedSwatch: Palette.Swatch? = palette.darkMutedSwatch

โดย Swatch นั้นคือชุดสีที่เอาไว้ใช้งานในแต่ละบริบท โดยจะแบ่งออกเป็น 2 ส่วนด้วยกันคือ สีของ Swatch และสีสำหรับตัวหนังสือเพื่อใช้แสดงบน Swatch นั้นๆ

val swatch: Palette.Swatch = /* ... */
val hsl: FloatArray = swatch.hsl
val rgb: Int = swatch.rgb
val titleTextColor: Int = swatch.titleTextColor
val bodyTextColor: Int = swatch.bodyTextColor
val population: Int = swatch.population

อยากจะใช้ค่าสีแบบ RGB หรือ HSL ก็เลือกได้ตามใจชอบ และยังบอกค่า Population มาให้ด้วย ซึ่งหมายถึงจำนวน Pixel ในภาพต้นฉบับที่มีค่าสีตรงกับ Swatch นั้นๆ

ส่วนสีตัวหนังสือจะแบ่งเป็น Title และ Body ที่สามารถแตกต่างกันได้ โดยขึ้นอยู่กับสีใน Swatch นั้นๆ

โดยข้อดีของการใช้สีตัวหนังสือจาก Swatch คือผ่านการคำนวณค่าสีให้เหมาะสมเรียบร้อยแล้ว โดยจะเลือกสีที่ตัดกับสีของ Swatch โดยที่ Contrast ไม่สูงมาก เพื่อไม่ให้ผู้ใช้รู้สึกปวดตาจากการมองสีที่ตัดกันจนเกินไป

สรุป

Palette API ถือว่าเป็น Library ที่จะช่วยให้นักพัฒนาสามารถเพิ่มลูกเล่นเกี่ยวกับสีใน UI ได้มากขึ้นโดยที่ไม่ต้องเขียนเองให้ยุ่งยาก ไม่ต้องปวดหัวกับการดึงสีจากภาพ และไม่ต้องกังวลว่าสีของตัวหนังสือจะกลืนไปกับสีพื้นหลังเลย เพราะทุกอย่างถูกจัดการไว้เรียบร้อยแล้วใน Palette API นั่นเอง

เอาล่ะ มาเพิ่มสีสันให้กับแอปกันเถอะ!!