Swift - 直接改內(nèi)存實(shí)現(xiàn)圖片圓角

參考自文章:http://www.itdecent.cn/p/bbb50b2cb7e6
以下是關(guān)鍵方法的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<UInt8>, 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<UInt32>.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
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,058評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,359評(píng)論 4 61
  • 只是跟他呆在一起的時(shí)候很開心,很自在,也不會(huì)計(jì)較什么。 只是我有男朋友,他有喜歡的人。 他覺得我很傻,我也認(rèn)為他二...
    王曉曉DE小屋閱讀 251評(píng)論 0 0
  • 10點(diǎn)起床,打開郵箱發(fā)現(xiàn)鏟子騎士打折了,立即購買。玩了一小時(shí)繼續(xù)看python的函數(shù)式編程。 1點(diǎn)和臟好人去吃午飯...
    AJI米閱讀 188評(píng)論 0 0
  • 一,.為自己開設(shè)的店鋪里的某款具體產(chǎn)品,按照花卷app產(chǎn)品推介6模塊進(jìn)行描述(建議下載app或登錄職教云app查看...
    68b183b38b2b閱讀 419評(píng)論 0 0

友情鏈接更多精彩內(nèi)容