Swift - 메모 리 를 직접 바 꾸 어 그림 의 원 각 을 실현 합 니 다.

참고 글:http://www.jianshu.com/p/bbb50b2cb7e6 다음은 관건 적 인 방법의 Swift 표기 법.
func dealImage(_ img: UIImage, cornerRadius c: CGFloat) -> UIImage? {
    
    guard
        let sourceData = img.cgImage?.dataProvider?.data,
        let mutableSourceData = CFDataCreateMutableCopy(kCFAllocatorDefault, CFDataGetLength(sourceData), sourceData),
        let mutablePointer = CFDataGetMutableBytePtr(mutableSourceData)
    else { return nil }
    
    let width = Int(img.size.width * img.scale)
    let height = Int(img.size.height * img.scale)

    cornerImage(at: mutablePointer, w: width, h: height, cornerRadius: c)
    
    guard let pv = CGDataProvider(dataInfo: nil,
                                  data: UnsafeRawPointer(mutablePointer),
                                  size: width * height * 4,
                                  releaseData: { (info, data, size) in
                                    free(UnsafeMutableRawPointer(mutating: data))
    }) else { return nil }
    
    let alphaPremultipliedLast = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
    
    guard let content = CGImage(
        width: width,
        height: height,
        bitsPerComponent: 8,
        bitsPerPixel: 32,
        bytesPerRow: 4 * width,
        space: CGColorSpaceCreateDeviceRGB(),
        bitmapInfo: [.byteOrder32Big, alphaPremultipliedLast],
        provider: pv,
        decode: nil,
        shouldInterpolate: true,
        intent: .defaultIntent) else { return nil }
    let result = UIImage(cgImage: content)
    return result
}

func cornerImage(at pointer: UnsafeMutablePointer, w: Int, h: Int, cornerRadius: CGFloat) {
    let min = CGFloat(w > h ? h : w)
    let c: Int = {
        var c = cornerRadius
        if c < 0 { c = 0 }
        if c > min * 0.5 { c = 0.5 }
        return Int(c)
    }()
    
    let pixelPointer = unsafeBitCast(pointer, to: UnsafeMutablePointer.self)
    
    //    y:[0, c), x:[0, c-y)
    for y in 0 ..< c {
        for x in 0 ..< c - y {
            if outsideCircle(cx: c, cy: c, r: c, px: x, py: y) {
                pixelPointer[y * w + x] = 0
            }
        }
    }
    
    //   
    for y in 0 ..< c {
        for x in w - c - y ..< w {
            if outsideCircle(cx: w - c, cy: c, r: c, px: x, py: y) {
                pixelPointer[y * w + x] = 0
            }
        }
    }
    
    //   
    for y in h - c ..< h {
        for x in 0 ..< y - (h - c) {
            if outsideCircle(cx: c, cy: h - c, r: c, px: x, py: y) {
                pixelPointer[y * w + x] = 0
            }
        }
    }
    
    //   
    for y in h - c ..< h {
        for x in w - c + (h - y) ..< w {
            if outsideCircle(cx: w - c, cy: h - c, r: c, px: x, py: y) {
                pixelPointer[y * w + x] = 0
            }
        }
    }
}

func outsideCircle(cx: Int, cy: Int, r: Int, px: Int, py: Int) -> Bool {
    return (cx - px) * (cx - px) + (cy - py) * (cy - py) > r * r
}

좋은 웹페이지 즐겨찾기