web-dev-qa-db-ja.com

UIColorプリセットからRGB値を取得する

私のアプリケーションでは、RGBカラー値をサーバーに渡します。私のアプリは、[UIColor GrayColor]、[UIColorredColor]などのUIColor定義済み値を使用しています。次のコードを使用できることを知っています。

const CGFloat *c = CGColorGetComponents(color.CGColor)

ただし、RBG色空間にある色の場合のみ、[UIColorgrayColor]はそうではありません。

非RBGカラーのRGB値を取得する方法はありますか?

ありがとう!

19
lstipakov

UIColorには、iOS 7以降でうまく機能するRGBコンポーネント(-getRed:green:blue:alpha:)を提供するメソッドがあります。 iOS 6以前では、色がRGB色空間にない場合、このメソッドは失敗し、NOを返します([UIColor grayColor]の場合と同様)。

IOS 6以前の場合、すべての色空間で機能するこれを行うために私が知っている唯一の方法は、RGB色空間でコアグラフィックスビットマップコンテキストを作成し、それに自分の色で描画することです。次に、結果のビットマップからRGB値を読み取ることができます。これは、適切なRGB値を持たないパターンカラー([UIColor groupTableViewBackgroundColor]など)などの特定のカラーでは機能しないことに注意してください。

- (void)getRGBComponents:(CGFloat [3])components forColor:(UIColor *)color {
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char resultingPixel[4];
    CGContextRef context = CGBitmapContextCreate(&resultingPixel,
                                                 1,
                                                 1,
                                                 8,
                                                 4,
                                                 rgbColorSpace,
                                                 kCGImageAlphaNoneSkipLast);
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, CGRectMake(0, 0, 1, 1));
    CGContextRelease(context);
    CGColorSpaceRelease(rgbColorSpace);

    for (int component = 0; component < 3; component++) {
        components[component] = resultingPixel[component] / 255.0f;
    }
}

次のように使用できます。

    CGFloat components[3];
    [self getRGBComponents:components forColor:[UIColor grayColor]];
    NSLog(@"%f %f %f", components[0], components[1], components[2]);
44
Jesse Rusak

私はこれを行う正しい方法を1つだけ知っています—それはCGGetColorComponents()を呼び出すことです。 UIColor-getRed:green:blue:alphaを使用してみましたが、グレースケールカラーでは正しく機能しません。だからここに私がすることです:

まず、RGBA色を簡単に操作できる単純なstructがあります。この構造は、ガンマ補正や色の平均化など、あらゆる種類の色操作を行うために他の場所で役立ちます。

typedef struct
{
  CGFloat r;  // Red component (0 <= r <= 1)
  CGFloat g;  // Green component (0 <= g <= 1)
  CGFloat b;  // Blue component (0 <= b <= 1)
  CGFloat a;  // Alpha/opacity component (0 <= a <= 1)
}
RGBA;

次に、RGBAを指定してUIColor構造体を返す関数があります。

RGBA RGBAFromUIColor(UIColor *color)
{
  return RGBAFromCGColor(color.CGColor);
}

UIColorCGColorを下位レベルの関数に渡して、手間のかかる作業を行います。

RGBA RGBAFromCGColor(CGColorRef color)
{
  RGBA rgba;

  CGColorSpaceRef color_space = CGColorGetColorSpace(color);
  CGColorSpaceModel color_space_model = CGColorSpaceGetModel(color_space);
  const CGFloat *color_components = CGColorGetComponents(color);
  int color_component_count = CGColorGetNumberOfComponents(color);

  switch (color_space_model)
  {
    case kCGColorSpaceModelMonochrome:
    {
      assert(color_component_count == 2);
      rgba = (RGBA)
      {
        .r = color_components[0],
        .g = color_components[0],
        .b = color_components[0],
        .a = color_components[1]
      };
      break;
    }

    case kCGColorSpaceModelRGB:
    {
      assert(color_component_count == 4);
      rgba = (RGBA)
      {
        .r = color_components[0],
        .g = color_components[1],
        .b = color_components[2],
        .a = color_components[3]
      };
      break;
    }

    default:
    {
      NSLog(@"Unsupported color space model %i", color_space_model);
      rgba = (RGBA) { 0, 0, 0, 0 };
      break;
    }
  }

  return rgba;
}

したがって、これはグレースケールカラー(UIColor.whiteColorUIColor.blackColorUIColor.grayColorなど)だけでなく、赤/緑/青/アルファカラーにも最適です。ただし、HSBカラーでは機能しません。

7
Todd Lehman

ジェシーの答えに加えて、アルファを保持する方法は次のとおりです。

- (void)getRGBAComponents:(CGFloat [4])components forColor:(UIColor *)color {
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char resultingPixel[4] = {0};
    CGContextRef context = CGBitmapContextCreate(&resultingPixel,
                                                 1,
                                                 1,
                                                 8,
                                                 4,
                                                 rgbColorSpace,
                                                 kCGImageAlphaPremultipliedLast);
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, CGRectMake(0, 0, 1, 1));
    CGContextRelease(context);
    CGColorSpaceRelease(rgbColorSpace);

    CGFloat a = resultingPixel[3] / 255.0;
    CGFloat unpremultiply = (a != 0.0) ? 1.0 / a / 255.0 : 0.0;
    for (int component = 0; component < 3; component++) {
        components[component] = resultingPixel[component] * unpremultiply;
    }
    components[3] = a;
}
3
nschmidt

「ある色空間から別の色空間に色を変換する方法」に対する私の答え からのクロスポスト。

さまざまな色空間を識別するために、色のCGColorSpaceModelからCGColorSpaceRefを取得できます。

UIColor* color = some color;
CGColorSpaceRef colorSpace = CGColorGetColorSpace([color CGColor]);
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);

次に、colorSpaceModelCoreGraphics/CGColorSpace.hで定義された定数と比較できます。 UIColorのgetRed:green:blue:alphakCGColorSpaceModelRGBで機能しますが、getWhite:alphakCGColorSpaceModelMonochromeで機能します。

1
damian

これを使用するだけでRGB値を取得できます

UIColor *chooseColor = view.backgroundColor;
CGFloat red,green,blue,alpha;

[chooseColor getRed:&red green:&green blue:&blue alpha:&alpha]; 

ありがとう:-)

0
Waseem Shah