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 นั่นเองเอาล่ะ มาเพิ่มสีสันให้กับแอปกันเถอะ!!