iOS 保存图片 最简单的方法 就是这个了
func UIImageWriteToSavedPhotosAlbum(_ image: UIImage, _ completionTarget: Any?, _ completionSelector: Selector?, _ contextInfo: UnsafeMutableRawPointer?)
同时这个方法还有个 固定写法的 Selector
@objc func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer)
但是 当iOS12 美滋滋的用上时 这个方法却给了我一个坑:
点击保存 -> 相册里找图片 0.0 !!! -> 图片呢?!!!!!
赶紧查看代码 image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafeRawPointer) 这个方法有正确调用 但是。。。 error 呢?! image 是有值的 !contextInfo 传的时候就是 nil ,苹果改方法了?弃用了? 都不是 。。。 最后发现 模拟器会报一个错:
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.}
这是说图片有问题,这个图片是自己生成的图片 是用的 UIImage.init(ciImage: CIImage) 创建的 UIImage ,也就是说 这张图片的本质是一张 CIImage (UIImage,CIImage,CGImage 相关的区别看这里)
那么是不是 CGImage才能保存呢? 试了下:
点击保存 -> 相册里找图片 -> 有了!!
接下来就简单了 (Swift之CIImage、CGImage、UIImage之间的相互转换)
CIImage转UIImage
/// CIImage转UIImage相对简单,直接使用UIImage的初始化方法即可
funcconvertCIImageToUIImage(ciImage:CIImage) ->UIImage{
letuiImage = UIImage.init(ciImage: ciImage)
// 注意!!!这里的uiImage的uiImage.cgImage 是nil
letcgImage = uiImage.cgImage
// 注意!!!上面的cgImage是nil,原因如下,官方解释
// returns underlying CGImageRef or nil if CIImage based
returnuiImage
}
CGImage转UIImage
// CGImage转UIImage相对简单,直接使用UIImage的初始化方法即可
// 原理同上
funcconvertCIImageToUIImage(cgImage:CGImage) ->UIImage{
letuiImage = UIImage.init(cgImage: cgImage)
// 注意!!!这里的uiImage的uiImage.ciImage 是nil
letciImage = uiImage.ciImage
// 注意!!!上面的ciImage是nil,原因如下,官方解释
// returns underlying CIImage or nil if CGImageRef based
returnuiImage
}
CGImage与CIImage互相转换
// 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转为CGImage、CIImage
/// UIImage转为CIImage
/// UIImage转CIImage有时候不能直接采用uiImage.ciImage获取
/// 当uiImage.ciImage为nil的时候需要先通过uiImage.cgImage得到
/// cgImage, 然后通过convertCGImageToCIImage将cgImage装换为ciImage
funcconvertUIImageToCIImage(uiImage:UIImage) ->CIImage{
varciImage = uiImage.ciImage
ifciImage ==nil{
letcgImage = uiImage.cgImage
ciImage =self.convertCGImageToCIImage(cgImage: cgImage!)
}
returnciImage!
}
/// UIImage转为CGImage
/// UIImage转CGImage有时候不能直接采用uiImage.cgImage获取
/// 当uiImage.cgImage为nil的时候需要先通过uiImage.ciImage得到
/// ciImage, 然后通过convertCIImageToCGImage将ciImage装换为cgImage
funcconvertUIImageToCGImage(uiImage:UIImage) ->CGImage{
varcgImage = uiImage.cgImage
ifcgImage ==nil{
letciImage = uiImage.ciImage
cgImage =self.convertCIImageToCGImage(ciImage: ciImage!)
}
returncgImage!
}
// 通过UIImage.init(named: "image.png") 得到的uiImage
// 默认是通过CGImageRef得到的因此uiImage的uiImage.ciImage为nil
letuiImage = UIImage.init(named:"image.png")
// cgImage有值
letcgImage = uiImage.cgImage
// ciImage为nil
letciImage = uiImage.ciImage
UIImage转Data
// 只有当uiImage.cgImage有值的时候才可以使用UIImagePNGRepresentation(_ image: UIImage)
// 或者UIImageJPEGRepresentation(_ image: UIImage, _ compressionQuality: CGFloat)转换为Data
funcconvertUIImageToData(uiImage:UIImage) ->Data{
vardata = UIImagePNGRepresentation(uiImage)
ifdata ==nil{
letcgImage =self.convertUIImageToCGImage(uiImage: uiImage)
letuiImage_ = UIImage.init(cgImage: cgImage)
data = UIImagePNGRepresentation(uiImage_)
}
returndata!
}