2017-08-20 9 views
3

私はこれらのlinks-CAGradientLayerを使用してグラデーションカラーホイールを描画する方法は?

からいくつかの参照を得ました

私は「HSVカラースペース」のコンセプトを使いました。しかし、私はCAGradientLayerの助けを借りてRGBを使ってカラーホイールを描画したいと思います。 getAngleAt()getArcPath()角度でパスを描くプライベート関数である

func drawColorWheel() 
{ 
    context?.saveGState() 

    range = CGFloat(100.00/CGFloat(colorArray.count)) 

    for k in 0 ..< colorArray.count 
    { 

     drawSlice(startPercent: CGFloat(k) * range, endPercent: CGFloat(CGFloat(k + 1) * range), color: colorArray.object(at: k) as! UIColor) 
    } 

    context?.restoreGState() 
} 

func drawSlice(startPercent: CGFloat, endPercent: CGFloat, color: UIColor) 
{   
    let startAngle = getAngleAt(percentage: startPercent) 
    let endAngle = getAngleAt(percentage: endPercent) 

    let path = getArcPath(startAngle: startAngle, endAngle: endAngle) 
    color.setFill() 
    path.fill() 
} 

- ここ

は、単純なRGB色アレイ及びUIBezierPathを使用して、カラーホイールを作るのコードスニペットです。 color wheel

私の質問は、各色がグラデーションカラー層にアップミックスするようにどのようにこれらの色にグラデーション効果を与えることです、今 -

ここに私のコードの最終出力はありますか?

答えて

6

一つのアプローチ画像を作成し、手動でピクセルバッファを操作することである。

  • 特定のサイズおよび特定のタイプのCGContextを作成します。
  • dataプロパティを介してデータバッファにアクセスします。
  • そのバッファを操作しやすくするために再バインドします(ピクセルの32ビット表現にはPixelstructを使用します)。
  • このイメージ内の円のangleradiusにピクセルを1つずつループします。
  • 円の内側にある場合は、適切な色のピクセルを作成します。そうでなければゼロアルファピクセルにします。
  • スウィフト3でそう

利回り
func buildHueCircle(in rect: CGRect, radius: CGFloat, scale: CGFloat = UIScreen.main.scale) -> UIImage? { 
    let width = Int(rect.size.width * scale) 
    let height = Int(rect.size.height * scale) 
    let center = CGPoint(x: width/2, y: height/2) 

    let space = CGColorSpaceCreateDeviceRGB() 
    let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width * 4, space: space, bitmapInfo: Pixel.bitmapInfo)! 

    let buffer = context.data! 

    let pixels = buffer.bindMemory(to: Pixel.self, capacity: width * height) 
    var pixel: Pixel 
    for y in 0 ..< height { 
     for x in 0 ..< width { 
      let angle = fmod(atan2(CGFloat(x) - center.x, CGFloat(y) - center.y) + 2 * .pi, 2 * .pi) 
      let distance = hypot(CGFloat(x) - center.x, CGFloat(y) - center.y) 

      let value = UIColor(hue: angle/2/.pi, saturation: 1, brightness: 1, alpha: 1) 

      var red: CGFloat = 0 
      var green: CGFloat = 0 
      var blue: CGFloat = 0 
      var alpha: CGFloat = 0 
      value.getRed(&red, green: &green, blue: &blue, alpha: &alpha) 

      if distance <= (radius * scale) { 
       pixel = Pixel(red: UInt8(red * 255), 
           green: UInt8(green * 255), 
           blue: UInt8(blue * 255), 
           alpha: UInt8(alpha * 255)) 
      } else { 
       pixel = Pixel(red: 255, green: 255, blue: 255, alpha: 0) 
      } 
      pixels[y * width + x] = pixel 
     } 
    } 

    let cgImage = context.makeImage()! 
    return UIImage(cgImage: cgImage, scale: scale, orientation: .up) 
} 

struct Pixel: Equatable { 
    private var rgba: UInt32 

    var red: UInt8 { 
     return UInt8((rgba >> 24) & 255) 
    } 

    var green: UInt8 { 
     return UInt8((rgba >> 16) & 255) 
    } 

    var blue: UInt8 { 
     return UInt8((rgba >> 8) & 255) 
    } 

    var alpha: UInt8 { 
     return UInt8((rgba >> 0) & 255) 
    } 

    init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) { 
     rgba = (UInt32(red) << 24) | (UInt32(green) << 16) | (UInt32(blue) << 8) | (UInt32(alpha) << 0) 
    } 

    static let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue 

    static func ==(lhs: Pixel, rhs: Pixel) -> Bool { 
     return lhs.rgba == rhs.rgba 
    } 
} 

constant saturation color wheel

それとも、半径に基づいて明度や彩度を調整することができます:

adjusting brightness

+0

恐ろしい答え+1 –

関連する問題