اختيار الألوان باستخدام Palette API

يُعد التصميم المرئي الجيد أمرًا ضروريًا لنجاح التطبيق، كما أنّ أنظمة الألوان هي أحد المكوّنات الأساسية للتصميم. مكتبة Palette هي إحدى مكتبات Jetpack التي تستخرج الألوان البارزة من الصور لإنشاء تطبيقات جذابة بصريًا.

يمكنك استخدام مكتبة Palette لتصميم مظاهر التنسيق وتطبيق ألوان مخصّصة على العناصر المرئية في تطبيقك. على سبيل المثال، يمكنك استخدام لوحة ألوان لإنشاء بطاقة عنوان منسّقة الألوان لأغنية استنادًا إلى غلاف الألبوم أو لتعديل لون شريط الأدوات في تطبيق عند تغيير صورة الخلفية. يمنحك العنصر Palette إمكانية الوصول إلى الألوان في صورة Bitmap، ويوفّر أيضًا ستة ملفات تعريف رئيسية للألوان من الصورة النقطية لإرشادك بشأن خيارات التصميم.

إعداد المكتبة

لاستخدام مكتبة Palette، أضِف ما يلي إلى build.gradle:

Kotlin

android {
    compileSdkVersion(33)
    ...
}

dependencies {
    ...
    implementation("androidx.palette:palette:1.0.0")
}

Groovy

android {
    compileSdkVersion 33
    ...
}

dependencies {
    ...
    implementation 'androidx.palette:palette:1.0.0'
}

إنشاء لوحة ألوان

يمنحك عنصر Palette إمكانية الوصول إلى الألوان الأساسية في صورة، بالإضافة إلى الألوان المقابلة للنص الذي يتم عرضه فوق الصورة. استخدِم لوحات الألوان لتصميم نمط تطبيقك وتغيير نظام الألوان في تطبيقك بشكل ديناميكي استنادًا إلى صورة مصدر معيّنة.

لإنشاء لوحة ألوان، عليك أولاً إنشاء مثيل من Palette.Builder من Bitmap. يمكنك بعد ذلك استخدام Palette.Builder لتخصيص لوحة الألوان قبل إنشائها. يوضّح هذا القسم كيفية إنشاء لوحة ألوان وتخصيصها من صورة نقطية.

إنشاء مثيل Palette

أنشئ مثيلاً من Palette باستخدام طريقة from(Bitmap bitmap) لإنشاء Palette.Builder من Bitmap أولاً.

يمكن لأداة الإنشاء إنشاء لوحة الألوان بشكل متزامن أو غير متزامن. استخدِم ميزة إنشاء لوحة الألوان المتزامنة إذا كنت تريد إنشاء لوحة الألوان على سلسلة المحادثات نفسها التي يتم استدعاء الطريقة عليها. إذا أنشأت لوحة الألوان بشكل غير متزامن، في سلسلة محادثات مختلفة، استخدِم طريقة onGenerated() للوصول إلى لوحة الألوان فور إنشائها.

يقدّم مقتطف الرمز التالي أمثلة على طرق إنشاء كلا النوعين من لوحات الألوان:

Kotlin

// Generate palette synchronously and return it.
fun createPaletteSync(bitmap: Bitmap): Palette = Palette.from(bitmap).generate()

// Generate palette asynchronously and use it on a different thread using onGenerated().
fun createPaletteAsync(bitmap: Bitmap) {
    Palette.from(bitmap).generate { palette ->
        // Use generated instance.
    }
}

Java

// Generate palette synchronously and return it.
public Palette createPaletteSync(Bitmap bitmap) {
  Palette p = Palette.from(bitmap).generate();
  return p;
}

// Generate palette asynchronously and use it on a different thread using onGenerated().
public void createPaletteAsync(Bitmap bitmap) {
  Palette.from(bitmap).generate(new PaletteAsyncListener() {
    public void onGenerated(Palette p) {
      // Use generated instance.
    }
  });
}

إذا كنت بحاجة إلى إنشاء لوحات ألوان بشكل مستمر لقائمة مرتّبة من الصور أو العناصر، ننصحك بتخزين مثيلات Palette مؤقتًا لتجنُّب بطء أداء واجهة المستخدم. لا تنشئ لوحات الألوان على الخيط الرئيسي.

تخصيص لوحة الألوان

تتيح لك الأداة Palette.Builder تخصيص لوحة الألوان من خلال اختيار عدد الألوان التي ستتضمّنها اللوحة الناتجة، والمساحة التي تستخدمها الأداة من صورتك لإنشاء اللوحة، والألوان التي ستتضمّنها اللوحة. على سبيل المثال، يمكنك فلترة اللون الأسود أو التأكّد من أنّ أداة الإنشاء تستخدم فقط النصف العلوي من الصورة لإنشاء لوحة الألوان.

يمكنك ضبط حجم لوحة الألوان وألوانها بدقة باستخدام الطرق التالية من الفئة Palette.Builder:

addFilter()
تضيف هذه الطريقة فلترًا يشير إلى الألوان المسموح بها في لوحة الألوان الناتجة. مرِّر Palette.Filter الخاص بك وعدِّل طريقة isAllowed() لتحديد الألوان التي سيتم فلترتها من لوحة الألوان.
maximumColorCount()
تحدّد هذه الطريقة الحدّ الأقصى لعدد الألوان في لوحة الألوان. القيمة التلقائية هي 16، وتعتمد القيمة المثالية على الصورة المصدر. بالنسبة إلى الصور الأفقية، تتراوح القيم المثالية بين 8 و16، بينما تتراوح القيم بين 24 و32 عادةً في الصور التي تتضمّن وجوهًا. يستغرق Palette.Builder وقتًا أطول لإنشاء لوحات ألوان تتضمّن المزيد من الألوان.
setRegion()
تشير هذه الطريقة إلى مساحة الصورة النقطية التي يستخدمها المنشئ عند إنشاء لوحة الألوان. لا يمكنك استخدام هذه الطريقة إلا عند إنشاء لوحة الألوان من صورة نقطية، ولا تؤثر في الصورة الأصلية.
addTarget()
تتيح لك هذه الطريقة مطابقة الألوان بنفسك من خلال إضافة ملف تعريف ألوان Target إلى أداة الإنشاء. إذا كان Target التلقائي غير كافٍ، يمكن للمطوّرين المتقدّمين إنشاء Target خاص بهم باستخدام Target.Builder.

استخراج ملفات تعريف الألوان

استنادًا إلى معايير Material Design، تستخرج مكتبة Palette ملفات تعريف الألوان الشائعة الاستخدام من صورة. يتم تحديد كل ملف شخصي من خلال Target، ويتم تقييم الألوان المستخرَجة من صورة نقطية مقابل كل ملف شخصي استنادًا إلى التشبع والسطوع والعدد (عدد وحدات البكسل في الصورة النقطية التي يمثلها اللون). بالنسبة إلى كل ملف تعريف، يحدّد اللون الذي يحقّق أفضل نتيجة ملف تعريف اللون هذا للصورة المحدّدة.

يتضمّن العنصر Palette تلقائيًا 16 لونًا أساسيًا من صورة معيّنة. عند إنشاء لوحة الألوان، يمكنك تخصيص عدد الألوان فيها باستخدام Palette.Builder. يؤدي استخراج المزيد من الألوان إلى توفير المزيد من التطابقات المحتملة لكل ملف ألوان، ولكنّه يؤدي أيضًا إلى استغراق Palette.Builderوقتًا أطول عند إنشاء لوحة الألوان.

تحاول مكتبة Palette استخراج ملفات تعريف الألوان الستة التالية:

  • Light Vibrant
  • نابض
  • Dark Vibrant
  • Light Muted
  • الصوت مكتوم
  • داكن باهت

تعرض كل طريقة من الطرق الست في get<Profile>Color() اللون في لوحة الألوان المرتبطة بهذا الملف الشخصي، ويتم استبدال <Profile> باسم أحد ملفات تعريف الألوان الستة.Palette على سبيل المثال، طريقة الحصول على ملف الألوان "الداكن الزاهي" هي getDarkVibrantColor(). بما أنّ بعض الصور لا تتضمّن جميع ملفات الألوان، يجب توفير لون تلقائي لعرضه.

تعرض "الشكل 1" صورة وملفات الألوان المقابلة لها من طرق get<Profile>Color().

صورة تعرض منظرًا لغروب الشمس على اليسار ولوحة الألوان المستخرَجة على اليمين
الشكل 1. صورة مثال وملفات تعريف الألوان المستخرَجة منها مع الأخذ في الاعتبار الحد الأقصى التلقائي لعدد الألوان (16) في لوحة الألوان

استخدام عيّنات الألوان لإنشاء مخططات ألوان

تنشئ الفئة Palette أيضًا عناصر Palette.Swatch لكل ملف تعريف ألوان. تحتوي كائنات Palette.Swatch على اللون المرتبط بهذا الملف الشخصي بالإضافة إلى عدد البكسلات التي يتضمّنها اللون.

تحتوي عيّنات الألوان على طرق إضافية للوصول إلى مزيد من المعلومات حول ملف تعريف الألوان، مثل قيم HSL وعدد وحدات البكسل. يمكنك استخدام عيّنات الألوان للمساعدة في إنشاء أنظمة ألوان ومظاهر تطبيقات أكثر شمولاً باستخدام الطريقتَين getBodyTextColor() وgetTitleTextColor(). تعرض هذه الطرق ألوانًا مناسبة للاستخدام فوق لون عيّنة الألوان.

تعرض كل طريقة من الطرق الست get<Profile>Swatch() في Palette عيّنة اللون المرتبطة بهذا الملف الشخصي، حيث يتم استبدال <Profile> باسم أحد ملفات الألوان الستة. على الرغم من أنّ طرق get<Profile>Swatch() في لوحة الألوان لا تتطلّب مَعلمات قيمة تلقائية، فإنّها تعرض null إذا لم يكن الملف الشخصي المحدّد متوفّرًا في الصورة. لذلك، تحقَّق من أنّ عيّنة الألوان ليست فارغة قبل استخدامها. على سبيل المثال، يحصل الرمز التالي على لون نص العنوان من لوحة ألوان إذا لم يكن عيّنة Vibrant فارغة:

Kotlin

val vibrant = myPalette.vibrantSwatch
// In Kotlin, check for null before accessing properties on the vibrant swatch.
val titleColor = vibrant?.titleTextColor

Java

Palette.Swatch vibrant = myPalette.getVibrantSwatch();
if(vibrant != null){
    int titleColor = vibrant.getTitleTextColor();
    // ...
}

للوصول إلى جميع الألوان في لوحة الألوان، تعرض الطريقة getSwatches() قائمة بجميع عيّنات الألوان التي تم إنشاؤها من صورة، بما في ذلك ملفات تعريف الألوان الستة العادية.

يستخدم مقتطف الرمز البرمجي التالي الطرق الواردة في مقتطفات الرمز البرمجي السابقة لإنشاء لوحة ألوان بشكل متزامن، والحصول على عيّنة الألوان الزاهية، وتغيير ألوان شريط الأدوات لتتطابق مع صورة نقطية. يعرض الشكل 2 الصورة الناتجة وشريط الأدوات.

Kotlin

// Set the background and text colors of a toolbar given a bitmap image to
// match.
fun setToolbarColor(bitmap: Bitmap) {
    // Generate the palette and get the vibrant swatch.
    val vibrantSwatch = createPaletteSync(bitmap).vibrantSwatch

    // Set the toolbar background and text colors.
    // Fall back to default colors if the vibrant swatch isn't available.
    with(findViewById<Toolbar>(R.id.toolbar)) {
        setBackgroundColor(vibrantSwatch?.rgb ?:
                ContextCompat.getColor(context, R.color.default_title_background))
        setTitleTextColor(vibrantSwatch?.titleTextColor ?:
                ContextCompat.getColor(context, R.color.default_title_color))
    }
}

Java

// Set the background and text colors of a toolbar given a bitmap image to
// match.
public void setToolbarColor(Bitmap bitmap) {
    // Generate the palette and get the vibrant swatch.
    // See the createPaletteSync() method from the preceding code snippet.
    Palette p = createPaletteSync(bitmap);
    Palette.Swatch vibrantSwatch = p.getVibrantSwatch();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

    // Load default colors.
    int backgroundColor = ContextCompat.getColor(getContext(),
        R.color.default_title_background);
    int textColor = ContextCompat.getColor(getContext(),
        R.color.default_title_color);

    // Check that the Vibrant swatch is available.
    if(vibrantSwatch != null){
        backgroundColor = vibrantSwatch.getRgb();
        textColor = vibrantSwatch.getTitleTextColor();
    }

    // Set the toolbar background and text colors.
    toolbar.setBackgroundColor(backgroundColor);
        toolbar.setTitleTextColor(textColor);
}
صورة تعرض غروب الشمس وشريط أدوات يحتوي على TitleTextColor
الشكل 2. صورة مثال مع شريط أدوات بألوان زاهية ولون نص العنوان المطابق