Как правильно получить цветовые компоненты CGColor

У меня есть UILabel с черным цветом;

я пишу следующий код, чтобы получить компоненты черного цвета.

UIColor *aColor = [aLabel.textColor retain];
const CGFloat* components = CGColorGetComponents(aColor.CGColor);
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();

но всегда это дает компоненты зеленого цвета вместо компонентов черного цвета;

Кто-нибудь имеет представление об этом?

Я передаю другое цветовое пространство?

:-(Пожалуйста, помогите мне.

5 ответов

Решение

Скорее всего, неправильное цветовое пространство. Я предполагаю, что альфа-компонент цветового пространства в градациях серого достигает того места, где, как вы думаете, должен быть зеленый компонент.
Я использую эту функцию для создания строки из UIColor, я сталкиваюсь только с цветовыми пространствами RGB и Grayscale, поэтому я просто интерпретирую каждый цвет с менее чем 4 (R+G+B+A) компонентами как оттенки серого.

if (CGColorGetNumberOfComponents(color.CGColor) < 4) {
    const CGFloat *components = CGColorGetComponents(color.CGColor);
    color = [UIColor colorWithRed:components[0] green:components[0] blue:components[0] alpha:components[1]];
}
if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) != kCGColorSpaceModelRGB) {
    NSLog(@"no rgb colorspace");
    // do seomthing
}
const CGFloat *components = CGColorGetComponents(color.CGColor);
NSString *colorAsString = [NSString stringWithFormat:@"%f,%f,%f,%f", components[0], components[1], components[2], components[3]];

Конечно, этот метод не подходит для всех случаев, вы должны принять его в соответствии с вашими требованиями.

Причина, по которой вы видите, как выглядит r=0, g=1, b=0, a=0 потому что вы неправильно интерпретируете значения в возвращаемом массиве как находящиеся в RGB цветовая модель. UIColor использует монохромное цветовое пространство для оттенков серого, например, черного.
То, что вы видите, это массив 2 компоненты из монохромной цветовой модели. Первый уровень серого (0 для черного) а второй альфа (1 для непрозрачных). Последние два значения, на которые вы смотрите, находятся за пределами 2 массив элементов и случается 0 в этом случае.

Вы заметите, если цвет черный, и вы попробуете CGColorGetNumberOfComponents(color.CGColor), это возвращает 2, И если вы попробуете CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)), это возвращает 0 что соответствует kCGColorSpaceModelMonochrome (см. enum CGColorSpaceModel в CGColorSpace.h)

см. Ссылку CGColorSpace

Я думаю, что это очень хороший способ получить представление rgb любого UIColor*, в котором уже есть удобный метод для сохранения его компонентов.

-(CGColorRef)CGColorRefFromUIColor:(UIColor*)newColor {
     CGFloat components[4] = {0.0,0.0,0.0,0.0};
     [newColor getRed:&components[0] green:&components[1] blue:&components[2]        alpha:&components[3]];
     CGColorRef newRGB = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components);
     return newRGB;
}

Один из способов получить RGB для них - нарисовать цвет в графическом контексте и прочитать его обратно. Смотрите мой ответ на этот вопрос, например, код:

Получить значение RGB из пресетов UIColor

Рабочий экзамен с UIColor: CALayer * btnLayer = [myLittleButton layer];

[layer setBackgroundColor:<#(CGColorRef)#>] будет выглядеть так: [btnLayer setBorderColor:[[UIColor grayColor] CGColor]];

просто убедитесь, что кнопки оригинальные цвета не покрывают слой

extension UIColor {

  func toRGB() -> UIColor? {
    guard let model = cgColor.colorSpace?.model else {
      return nil
    }
    
    let components = cgColor.components

    switch model {
    case .rgb:
      return UIColor(red: components?[0] ?? 0.0, green: components?[1] ?? 0.0, blue: components?[2] ?? 0.0, alpha: components?[3] ?? 0.0)
    case .monochrome:
      return UIColor(red: components?[0] ?? 0.0, green: components?[0] ?? 0.0, blue: components?[0] ?? 0.0, alpha: components?[1] ?? 0.0)
    default:
      return nil
    }
  }
}
Другие вопросы по тегам