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

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

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

การทำแบบนี้ได้ก็มาจากการคำนวนค่าสีที่อยู่บนภาพนั่นแหละ ซึ่ง Palette API ก็เกิดมาเพื่องานนี้นี่เอง

โดย 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 เข้ามาในโปรเจคดังนี้

implementation 'androidx.palette.palette:1.0.0'


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

val bitmap: Bitmap = ... // Synchronous val palette: Palette = Palette.from(bitmap).generate() // Asynchronous Palette.from(bitmap).generate { palette: Palette? -> ... }


โดยค่าสีจาก Bitmap นั้นๆจะส่งออกมาได้ 2 แบบ คือ Synchronous และ Asynchronous ซึ่งเจ้าของบล็อกแนะนำว่าให้ใช้แบบ Asynchronous ดีกว่า เพราะว่าระยะเวลาในการดึงค่าสีของ Palette API นั้นขึ้นอยู่กับขนาดภาพ ดังนั้นถ้าภาพมีขนาดใหญ่ก็จะใช้เวลานานและทำให้ไปบล็อก UI Thread ดังนั้นการใช้แบบ Asynchronous จึงปลอดภัยกว่า

ค่าสีที่ได้นั้นจะส่งออกมาเป็นคลาส Palette นั่นแหละ ซึ่งในนั้นก็จะมีค่าสีต่างๆตามที่เจ้าของบล็อกอธิบายไว้ในตอนแรก สามารถดึงค่ามาใช้งานได้เลย

val defaultColor: Int = Color.WHITE val palette: Palette = ... 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: Swatch? = palette.getLightVibrantSwatch() val vibrantSwatch: Swatch? = palette.getVibrantSwatch() val darkVibrantSwatch: Swatch? = palette.getDarkVibrantSwatch() val lightMutedSwatch: Swatch? = palette.getLightMutedSwatch() val mutedSwatch: Swatch? = palette.getMutedSwatch() val darkMutedSwatch: Swatch? = palette.getDarkMutedSwatch()


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

val palette: Palette = ... val swatch: Palette.Swatch? = palette.getVibrantSwatch() swatch?.let { val hsl: FloatArray = swatch.getHsl() val rgb: Int = swatch.getRgb() val bodyTextColor: Int = swatch.getBodyTextColor() val titleTextColor: Int = swatch.getTitleTextColor() val population = swatch.getPopulation() }


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

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

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

สรุป


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

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