1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/CarGuo-GSYFlutterBook

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Flutter-wide.md 13 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 10.03.2025 00:06 5767d61

В Flutter произошли значительные изменения в цветовой модели, теперь требуется адаптация для перехода. Цвет больше не представлен значениями от 0 до 255, а используется диапазон от 0 до 1.0, что позволяет поддерживать более широкий спектр цветов.

В версии 3.10 Flutter начал поддерживать P3 широкого цветового пространства для отрисовки изображений с помощью Impeller на устройствах iOS. Однако тогда эта поддержка была активна только при наличии изображений или градиентов с широким цветовым пространством. Если вы использовали API Color, то заметили бы, что отрисовка всё ещё происходит в цветовом пространстве sRGB.

⚠️ Если вас не интересует причина и необходимость корректировки, вы можете сразу перейти к разделу адаптации.

Какие различия между sRGB и P3? Проще говоря, самое очевидное отличие можно видеть на следующих изображениях. На устройствах с поддержкой P3 цветового пространства P3 обеспечивает более широкий спектр цветов, поэтому вы видите более яркие и насыщенные цвета, а большинство мобильных устройств уже поддерживают P3 цветовое пространство в 2024 году.

Просто сравните цветовые пространства sRGB (белый треугольник) и Display P3 (оранжевый треугольник) на следующем изображении. Из пропорций следует, что P3 широкое цветовое пространство может поддерживать как минимум на 25% больше цветов по сравнению со sRGB.

Конечно, в версии 3.10 Flutter поддерживал широкое цветовое пространство только для отрисовки изображений с помощью Impeller, но для использования API Color всё ещё применялось цветовое пространство sRGB. Это значит, что API для отрисовки широкого цветового пространства в Flutter Widgets пока недоступно.

Поэтому команда Flutter начала работу над рефакторингом объекта Color в 2023 году, чтобы сделать его способным поддерживать P3 широкое цветовое пространство. Самым очевидным изменением стало то, что ранее диапазон допустимых значений составлял [0, 255], а теперь каждый компонент цвета представлен в виде числа с плавающей запятой в диапазоне [0, 1.0].

Вы, возможно, удивлены тем, почему диапазон [0, 255] был заменён на [0, 1.0], но при этом цветовое пространство стало шире. Это связано с увеличением точности данных после того, как целочисленные значения были заменены на числа с плавающей запятой.> До этого каждое значение цвета в диапазоне [0, 255] представляло собой 8 бит, передаваемые из Dart в движок в виде ARGB (4x8) и упаковываемые в одноцелочисленное число размером 32 бита (альфа-красный-синий-зелёный). Каждый цвет занимает 8 бит (255), затем этот цвет преобразуется в SkColor Skia и далее в DlColor, который также представляет собой целочисленное значение.

В Impeller DlColor преобразуется в impeller::Color, который имеет размер 128 бит, где каждый цвет представлен в виде нормализованного числа с плавающей запятой размером 32 бита. Таким образом, точность данных значительно повышается за счет увеличения количества используемых бит. Почему повышение количества бит важно для поддержки цветового пространства? Потому что P3 охватывает больше цветов, чем позволяют 8 бит на канал, поэтому требуется как минимум 10 бит на канал для представления всех цветов P3.Очевидно, до этого Flutter использовал целочисленное представление sRGB [0, 255], где каждый цвет занимает 8 бит, а вместе они составляют всего 32 бита. В то время как использование представления с плавающей запятой [0–1.0] изменило эту ситуацию:

Начиная с версии 3.27 beta, dart:ui теперь использует Color, который может содержать до 320 бит вместо максимальных 64 бит.

Почему говорится о переходе от 64 бит до 320 бит? Потому что ранее в Color был только один целый тип данных int, который в Dart составляет 64 бита, следовательно, Color мог иметь максимум 64 бита. Теперь же добавлены четыре значения типа double: a, r, g, b. Каждое значение double имеет 64 бита, таким образом, Color теперь состоит из пяти значений, что даёт ему максимальные 320 бит. Однако в будущем значение value будет废弃不用.

То есть каждое из a, r, g, b теоретически может использовать до 64 бит, если не считать value, Color переходит от 64-битного целого числа к 256-битному числу с плавающей запятой.

image-20241024163722126

Затем компоненты отправляют данные о цветах в C++, а ранее было упомянуто, что в слое Engine DlColor также адаптирован к 128 бит для совместимости с impeller::Color, то есть DlColor состоит из четырёх 32-битных значений типа float, при этом поддерживаются старые версии sRGB цветового пространства.> Не обращайте внимания на различия между Dart/64 и C++/32, это просто особенность языка.

Кроме того, в ColorSpace добавлена возможность использования displayP3, что завершает базовую поддержку широкого цветового пространства. Но реальная поддержка P3 доступна пока только на iOS, а для Android потребуется более развитая поддержка Vulkan Impeller для дальнейшей оптимизации.

Изменения в коде

С изменениями в поддержке цвета внизу, API уровня Color также претерпели существенные изменения. Эти изменения можно назвать серьезной перестройкой, поскольку изменения цветового пространства сильно влияют на верхний уровень API. Например, рекомендация использовать fromARGB была заменена на использование Color.from.

// До
final малиновый = Color.fromARGB(0xff, 0xff, 0x0, 0xff);
// После
final малиновый = Color.from(alpha: 1.0, red: 1.0, green: 0.0, blue: 1.0)

Кроме того, ранее в Color существовало понятие -opacity, поэтому присутствовали методы opacity и withOpacity(). Введением opacity раньше хотели сделать так, чтобы Color имел альфа-канал с плавающей запятой, но теперь альфа — это просто число с плавающей запятой, поэтому использование opacity стало излишним. В будущем методы opacity и withOpacity() будут удалены:

// До
final x = color.opacity;
// После
final x = color.a;
``````dart
final x = color.withOpacity(0.0);

изображение

Кроме того, если вы используете наследование от Color, лучше временно заменить его на implements, то есть вам больше не потребуется реализовывать логику через super. Почему временно? Потому что команда Flutter планирует в будущем закрыть Color через sealed, поэтому внешних реализаций Color уже не будет.

class Foo implements Color {
  int _red;

  @override
  double get r => _red * 255.0;
}

Кроме того, при использовании Color и выполнении любых вычислений с цветами, следует сначала проверять пространство цветов (ColorSpace) этого цвета, прежде чем выполнять вычисления. Для выполнения преобразования пространства цветов рекомендуется использовать новый метод Color.withValues.

// До
double redRatio(Color x, Color y) => x.red / y.red;

// После
double redRatio(Color x, Color y) {
  final xPrime = x.withValues(colorSpace: ColorSpace.extendedSRGB);
  final yPrime = y.withValues(colorSpace: ColorSpace.extendedSRGB);
  return xPrime.r / yPrime.r;
}

Выполнение вычислений с цветами без учета совместимости пространств цветов может привести к небольшим ошибкам. Например, в примере выше, если используется другое пространство цветов вместо совместимого, разница в значении redRatio составит 0.09.

ПоследнееНа самом деле, хотя эти изменения могут показаться простым процессом конвертации в toDouble, они оказывают значительное влияние на UI Flutter. Независимо от адаптации цветовых API, изменений в способах вычислений или поддержки новых цветовых пространств, эти изменения действительно затрагивают широкий спектр областей. Такие изменения могут вызывать проблемы с границами рендера, поэтому слияние было отложено до бета-версии. Возможно, скоро мы сможем видеть эти изменения в официальной версии.Ссылки на справочные материалы:

https://github.com/flutter/flutter/issues/55092

https://github.com/dart-lang/sdk/issues/56363

https://github.com/flutter/flutter/issues/127852

https://github.com/flutter/flutter/issues/127855

https://docs.flutter.dev/release/breaking-changes/wide-gamut-framework

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/CarGuo-GSYFlutterBook.git
git@api.gitlife.ru:oschina-mirror/CarGuo-GSYFlutterBook.git
oschina-mirror
CarGuo-GSYFlutterBook
CarGuo-GSYFlutterBook
master