iOS 保存圖片 最簡(jiǎn)單的方法 就是這個(gè)了
func UIImageWriteToSavedPhotosAlbum(_ image: UIImage, _ completionTarget: Any?, _ completionSelector: Selector?, _ contextInfo: UnsafeMutableRawPointer?)
同時(shí)這個(gè)方法還有個(gè) 固定寫(xiě)法的?Selector?
@objc func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:?UnsafeRawPointer)
但是 當(dāng)iOS12 美滋滋的用上時(shí) 這個(gè)方法卻給了我一個(gè)坑:
點(diǎn)擊保存 -> 相冊(cè)里找圖片 0.0 1醢汀0小远舅! -> 圖片呢拆融?!!!R讶铡!
趕緊查看代碼?image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafeRawPointer)?這個(gè)方法有正確調(diào)用 但是栅屏。飘千。。 error 呢栈雳?护奈! image 是有值的 !contextInfo 傳的時(shí)候就是 nil 哥纫,蘋(píng)果改方法了霉旗?棄用了? 都不是 蛀骇。厌秒。。 最后發(fā)現(xiàn) 模擬器會(huì)報(bào)一個(gè)錯(cuò):
Error Domain=ALAssetsLibraryErrorDomain Code=-3300 "Write failed" UserInfo={NSUnderlyingError=0x600003d48240 {Error Domain=ALAssetsLibraryErrorDomain Code=-3300 "Write failed" UserInfo={NSUnderlyingError=0x600003d48120 {Error Domain=ALAssetsLibraryErrorDomain Code=-3300 "Write failed" UserInfo={NSUnderlyingError=0x600003cce130 {Error Domain=PersistentURLTranslator Code=10 "(null)"}, NSLocalizedDescription=Write failed, NSLocalizedFailureReason=There was a problem writing this asset because the write failed.}}, NSLocalizedDescription=Write failed, NSLocalizedFailureReason=There was a problem writing this asset because the write failed.}}, NSLocalizedDescription=Write failed, NSLocalizedFailureReason=There was a problem writing this asset because the write failed.}
這是說(shuō)圖片有問(wèn)題擅憔,這個(gè)圖片是自己生成的圖片 是用的 UIImage.init(ciImage: CIImage)? 創(chuàng)建的 UIImage 简僧,也就是說(shuō) 這張圖片的本質(zhì)是一張 CIImage (UIImage,CIImage,CGImage 相關(guān)的區(qū)別看這里)
那么是不是 CGImage才能保存呢? 試了下:
點(diǎn)擊保存 -> 相冊(cè)里找圖片 -> 有了5衿邸!
接下來(lái)就簡(jiǎn)單了 (Swift之CIImage棉姐、CGImage屠列、UIImage之間的相互轉(zhuǎn)換)
CIImage轉(zhuǎn)UIImage
/// CIImage轉(zhuǎn)UIImage相對(duì)簡(jiǎn)單,直接使用UIImage的初始化方法即可
funcconvertCIImageToUIImage(ciImage:CIImage) ->UIImage{
? ? letuiImage = UIImage.init(ciImage: ciImage)
? ? // 注意I【亍5崖濉!這里的uiImage的uiImage.cgImage 是nil
? ? letcgImage = uiImage.cgImage
? ? // 注意D死ぁ?寥谩!上面的cgImage是nil湿诊,原因如下狱杰,官方解釋
? ? // returns underlying CGImageRef or nil if CIImage based
? ? returnuiImage
}
CGImage轉(zhuǎn)UIImage
// CGImage轉(zhuǎn)UIImage相對(duì)簡(jiǎn)單,直接使用UIImage的初始化方法即可
// 原理同上
funcconvertCIImageToUIImage(cgImage:CGImage) ->UIImage{
? ? letuiImage = UIImage.init(cgImage: cgImage)
? ? // 注意L搿7禄!這里的uiImage的uiImage.ciImage 是nil
? ? letciImage = uiImage.ciImage
? ? // 注意!4砉痢簿晓!上面的ciImage是nil,原因如下千埃,官方解釋
? ? // returns underlying CIImage or nil if CGImageRef based
? ? returnuiImage
}
CGImage與CIImage互相轉(zhuǎn)換
// MARK:- convert the CGImageToCIImage
/// convertCGImageToCIImage
///
/// - Parameter cgImage: input cgImage
/// - Returns: output CIImage
funcconvertCGImageToCIImage(cgImage:CGImage) ->CIImage{
? ? returnCIImage.init(cgImage: cgImage)
}
// MARK:- convert the CIImageToCGImage
/// convertCIImageToCGImage
///
/// - Parameter ciImage: input ciImage
/// - Returns: output CGImage
funcconvertCIImageToCGImage(ciImage:CIImage) ->CGImage{
? ? letciContext = CIContext.init()
? ? letcgImage:CGImage= ciContext.createCGImage(ciImage, from: ciImage.extent)!
? ? returncgImage
}
UIImage轉(zhuǎn)為CGImage憔儿、CIImage
/// UIImage轉(zhuǎn)為CIImage
/// UIImage轉(zhuǎn)CIImage有時(shí)候不能直接采用uiImage.ciImage獲取
/// 當(dāng)uiImage.ciImage為nil的時(shí)候需要先通過(guò)uiImage.cgImage得到
/// cgImage, 然后通過(guò)convertCGImageToCIImage將cgImage裝換為ciImage
funcconvertUIImageToCIImage(uiImage:UIImage) ->CIImage{
? ? varciImage = uiImage.ciImage
? ? ifciImage ==nil{
? ? ? ? letcgImage = uiImage.cgImage
? ? ? ? ciImage =self.convertCGImageToCIImage(cgImage: cgImage!)
? ? }
? ? returnciImage!
}
/// UIImage轉(zhuǎn)為CGImage
/// UIImage轉(zhuǎn)CGImage有時(shí)候不能直接采用uiImage.cgImage獲取
/// 當(dāng)uiImage.cgImage為nil的時(shí)候需要先通過(guò)uiImage.ciImage得到
/// ciImage, 然后通過(guò)convertCIImageToCGImage將ciImage裝換為cgImage
funcconvertUIImageToCGImage(uiImage:UIImage) ->CGImage{
? ? varcgImage = uiImage.cgImage
? ? ifcgImage ==nil{
? ? ? ? letciImage = uiImage.ciImage
? ? ? ? cgImage =self.convertCIImageToCGImage(ciImage: ciImage!)
? ? }
? ? returncgImage!
}
// 通過(guò)UIImage.init(named: "image.png") 得到的uiImage
// 默認(rèn)是通過(guò)CGImageRef得到的因此uiImage的uiImage.ciImage為nil
letuiImage = UIImage.init(named:"image.png")
// cgImage有值
letcgImage = uiImage.cgImage
// ciImage為nil
letciImage = uiImage.ciImage
UIImage轉(zhuǎn)Data
// 只有當(dāng)uiImage.cgImage有值的時(shí)候才可以使用UIImagePNGRepresentation(_ image: UIImage)
// 或者UIImageJPEGRepresentation(_ image: UIImage, _ compressionQuality: CGFloat)轉(zhuǎn)換為Data
funcconvertUIImageToData(uiImage:UIImage) ->Data{
? ? vardata = UIImagePNGRepresentation(uiImage)
? ? ifdata ==nil{
? ? ? ? letcgImage =self.convertUIImageToCGImage(uiImage: uiImage)
? ? ? ? letuiImage_ = UIImage.init(cgImage: cgImage)
? ? ? ? data = UIImagePNGRepresentation(uiImage_)
? ? }
? ? returndata!
}