first commit

This commit is contained in:
2022-05-05 12:02:50 +08:00
parent 29c9db4a94
commit 3d72669c73
5 changed files with 254 additions and 3 deletions
+146
View File
@@ -0,0 +1,146 @@
//
// ColorWheelView.swift
// ColorWheel
//
// Created by on 2019/3/8.
//
import Foundation
import UIKit
// RGB
typealias RGB = (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
// HSV
typealias HSV = (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)
class ColorWheelView: UIView {
//
private let BORDER = 20.0
var wheelLayer: CALayer!
//
let scale: CGFloat = UIScreen.main.scale
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder);
}
override init(frame: CGRect) {
super.init(frame: frame)
// -
let width = self.frame.width - (BORDER * 2.0)
let height = self.frame.height - (BORDER * 2.0)
wheelLayer = CALayer()
wheelLayer.frame = CGRect(x: BORDER, y: BORDER, width: width, height: height)
wheelLayer.contents = createColorWheel(wheelLayer.frame.size)
self.layer.addSublayer(wheelLayer)
}
private func createColorWheel(_ size: CGSize) -> CGImage {
// -
let originalWidth = size.width
let originalHeight = size.height
let dimension = min(originalWidth * scale, originalHeight * scale)
let bufferLength = Int(dimension * dimension * 4) // * * (RGBA)
//
let bitmapData = CFDataCreateMutable(nil, 0)
CFDataSetLength(bitmapData, CFIndex(bufferLength))
let bitmap = CFDataGetMutableBytePtr(bitmapData)
//
for y in stride(from: CGFloat(0), to: dimension, by: CGFloat(1)) {
for x in stride(from: CGFloat(0), to: dimension, by: CGFloat(1)) {
var hsv: HSV = (hue: 0, saturation: 0, brightness: 0, alpha: 0)
var rgb: RGB = (red: 0, green: 0, blue: 0, alpha: 0)
let color = hueSaturationAtPoint(CGPoint(x: x, y: y))
let hue = color.hue
let saturation = color.saturation
var a: CGFloat = 0.0
if (saturation < 1.0) {
//
if (saturation > 0.99) {
a = (1.0 - saturation) * 100
} else {
a = 1.0;
}
hsv.hue = hue
hsv.saturation = saturation
hsv.brightness = 1.0
hsv.alpha = a
rgb = hsv2rgb(hsv)
}
let offset = Int(4 * (x + y * dimension))
bitmap?[offset] = UInt8(rgb.red*255)
bitmap?[offset + 1] = UInt8(rgb.green*255)
bitmap?[offset + 2] = UInt8(rgb.blue*255)
bitmap?[offset + 3] = UInt8(rgb.alpha*255)
}
}
// bitmap CGImage
let colorSpace = CGColorSpaceCreateDeviceRGB()
let dataProvider = CGDataProvider(data: bitmapData!)
let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo().rawValue | CGImageAlphaInfo.last.rawValue)
let imageRef = CGImage(width: Int(dimension), height: Int(dimension), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: Int(dimension) * 4, space: colorSpace, bitmapInfo: bitmapInfo, provider: dataProvider!, decode: nil, shouldInterpolate: false, intent: CGColorRenderingIntent.defaultIntent)
return imageRef!
}
//
func hueSaturationAtPoint(_ position: CGPoint) -> (hue: CGFloat, saturation: CGFloat) {
let c = wheelLayer.frame.width * scale / 2
let dx = CGFloat(position.x - c) / c
let dy = CGFloat(position.y - c) / c
let d = sqrt(CGFloat (dx * dx + dy * dy))
let saturation: CGFloat = d
var hue: CGFloat
if (d == 0) {
hue = 0;
} else {
hue = acos(dx/d) / CGFloat(Double.pi) / 2.0
if (dy < 0) {
hue = 1.0 - hue
}
}
return (hue, saturation)
}
// HSV RGB
func hsv2rgb(_ hsv: HSV) -> RGB {
var rgb: RGB = (red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
var r: CGFloat
var g: CGFloat
var b: CGFloat
let i = Int(hsv.hue * 6)
let f = hsv.hue * 6 - CGFloat(i)
let p = hsv.brightness * (1 - hsv.saturation)
let q = hsv.brightness * (1 - f * hsv.saturation)
let t = hsv.brightness * (1 - (1 - f) * hsv.saturation)
switch (i % 6) {
case 0: r = hsv.brightness; g = t; b = p; break;
case 1: r = q; g = hsv.brightness; b = p; break;
case 2: r = p; g = hsv.brightness; b = t; break;
case 3: r = p; g = q; b = hsv.brightness; break;
case 4: r = t; g = p; b = hsv.brightness; break;
case 5: r = hsv.brightness; g = p; b = q; break;
default: r = hsv.brightness; g = t; b = p;
}
rgb.red = r
rgb.green = g
rgb.blue = b
rgb.alpha = hsv.alpha
return rgb
}
}
+8 -1
View File
@@ -2,16 +2,23 @@
// ViewController.swift
// ColorWheel
//
// Created by on 2022/5/4.
// Created by on 2019/3/8.
//
import UIKit
class ViewController: UIViewController {
var colorWheelView: ColorWheelView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let size = self.view.frame.size.width
let frame = CGRect(x: 0, y: 84, width: size, height: size)
colorWheelView = ColorWheelView(frame: frame)
self.view.addSubview(colorWheelView!)
}
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
</view>
</objects>
</document>