为ColorPicker生成UIImage(CGDataProvider和CGImageSource)

时间:2017-01-27 16:51:27

标签: ios swift core-graphics cgimage

伙计我是swift和编程的新手,我想生成一个为ColorPicker显示的图像,我使用SwiftColorPicker进行创建,并使用以下代码进行图像创建:

 private func createImageFromData(_ width:Int, height:Int) {
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
    provider = CGDataProvider(data: mutableData)
    imageSource = CGImageSourceCreateWithDataProvider(provider, nil)
    let cgImage = CGImage.init(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: width * 4, space: colorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: true, intent: .defaultIntent)

    if let cgimg = cgImage {
        image = UIImage(cgImage: cgimg)

            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.creationRequestForAsset(from: self.image!)
            }, completionHandler: { success, error in
                if success {
                    print("succes")
                }
                else if let error = error {
                    print("error")
                    debugPrint(error as Any)
                }
                else {
                    print("woooot?")
                }
            })


    } else { print("Where the hell is the image?") }
}


func changeSize(_ width:Int, height:Int) {
    self.width = width
    self.height = height
    let size:Int = width * height * 4
    CFDataSetLength(mutableData, size)
    createImageFromData(width, height: height)
}

init(width:Int, height:Int) {
    self.width = width
    self.height = height
    let size:Int = width * height * 4
    mutableData = CFDataCreateMutable(kCFAllocatorDefault, size)
    createImageFromData(width, height: height)
}

public func writeColorData(_ h:CGFloat, a:CGFloat) {

    let d = CFDataGetMutableBytePtr(self.mutableData)

    if width == 0 || height == 0 {
        return
    }

    var i:Int = 0
    let h360:CGFloat = ((h == 1 ? 0 : h) * 360) / 60.0
    let sector:Int = Int(floor(h360))
    let f:CGFloat = h360 - CGFloat(sector)
    let f1:CGFloat = 1.0 - f
    var p:CGFloat = 0.0
    var q:CGFloat = 0.0
    var t:CGFloat = 0.0
    let sd:CGFloat = 1.0 / CGFloat(width)
    let vd:CGFloat =  1 / CGFloat(height)

    var double_s:CGFloat = 0
    var pf:CGFloat = 0
    let v_range = 0..<height
    let s_range = 0..<width

    for v in v_range {
        pf = 255 * CGFloat(v) * vd
        for s in s_range {
            i = (v * width + s) * 4
            d?[i] = UInt8(255)
            if s == 0 {
                q = pf
                d?[i+1] = UInt8(q)
                d?[i+2] = UInt8(q)
                d?[i+3] = UInt8(q)
                continue
            }

            double_s = CGFloat(s) * sd
            p = pf * (1.0 - double_s)
            q = pf * (1.0 - double_s * f)
            t = pf * ( 1.0 - double_s  * f1)
            switch(sector) {
            case 0:
                d?[i+1] = UInt8(pf)
                d?[i+2] = UInt8(t)
                d?[i+3] = UInt8(p)
            case 1:
                d?[i+1] = UInt8(q)
                d?[i+2] = UInt8(pf)
                d?[i+3] = UInt8(p)
            case 2:
                d?[i+1] = UInt8(p)
                d?[i+2] = UInt8(pf)
                d?[i+3] = UInt8(t)
            case 3:
                d?[i+1] = UInt8(p)
                d?[i+2] = UInt8(q)
                d?[i+3] = UInt8(pf)
            case 4:
                d?[i+1] = UInt8(t)
                d?[i+2] = UInt8(p)
                d?[i+3] = UInt8(pf)
            default:
                d?[i+1] = UInt8(pf)
                d?[i+2] = UInt8(p)
                d?[i+3] = UInt8(q)
            }


        }
    }
}

和:

    // Write colors to data array
        if self.data1Shown { self.pickerImage2!.writeColorData(self.h, a:self.a) }
        else { self.pickerImage1!.writeColorData(self.h, a:self.a)}

使用:

  public var a:CGFloat = 1 {
    didSet {
        if a < 0 || a > 1 {
            a = max(0, min(1, a))
        }
    }
}

public var h:CGFloat = 0 { // // [0,1]
    didSet {
        if h > 1 || h < 0 {
            h = max(0, min(1, h))
        }
        renderBitmap()
        setNeedsDisplay()
    }

}

当我尝试将其保存到相册时失败(我已经完成了因为我无法设置图像,所以我试图将其保存以了解它是否正常或它是否正确#39 ; sa错误),瞧!出现一个优雅的错误:

错误域= NSCocoaErrorDomain代码= -1&#34;(null)&#34;

所以我想知道也许有人知道该怎么做,我怎么能解决这个问题,这里是gitHub上关于Source的链接(也许会有所帮助):

https://github.com/MrMatthias/SwiftColorPicker

谢谢!

1 个答案:

答案 0 :(得分:0)

我已经做了一个有用的快速扩展来创建一个纯色的UIImage

随意使用它:

extension UIImage {

    static func image(of color: UIColor, size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)

        color.set()
        UIRectFill(CGRect(origin: CGPoint.zero, size: size))

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }

}

然后您可以通过以下方式使用它:

let redImage = UIImage.image(of: .red, size: CGSize(width: 200, height: 200))

希望有所帮助!