我正在使用UIImageWriteToSavedPhotosAlbum将UIImage保存到用户的相册中。问题是该图像没有透明度且为JPG格式。虽然我已经正确设置了像素数据以具有透明度,但似乎没有办法以支持透明度的格式保存。有什么想法?
编辑:无法实现这一点,但有其他方法向用户提供PNG图像。其中之一是将图像保存在文档目录中(如下所述)。完成后,可以通过电子邮件发送、保存在数据库中等方式使用它。除非是有损非透明JPG,否则您无法将其保存到相册中(目前)。
我正在使用UIImageWriteToSavedPhotosAlbum将UIImage保存到用户的相册中。问题是该图像没有透明度且为JPG格式。虽然我已经正确设置了像素数据以具有透明度,但似乎没有办法以支持透明度的格式保存。有什么想法?
编辑:无法实现这一点,但有其他方法向用户提供PNG图像。其中之一是将图像保存在文档目录中(如下所述)。完成后,可以通过电子邮件发送、保存在数据库中等方式使用它。除非是有损非透明JPG,否则您无法将其保存到相册中(目前)。
如此SO问题所指出的,有一种简单方法可以将PNG保存到您的相册中:
UIImage* image = ...; // produce your image
NSData* imageData = UIImagePNGRepresentation(image); // get png representation
UIImage* pngImage = [UIImage imageWithData:imageData]; // rewrap
UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil); // save to photo album
这是我以前注意到并在约一年前向Apple开发者论坛报告的问题。据我所知,它仍然是一个未解决的问题。
如果您有时间,请花点时间在Apple Bug Report上提交功能请求。如果更多人报告此问题,则苹果公司更有可能修复这种方法以输出非损失性、支持 alpha 的 PNG。
编辑
如果您可以在内存中组合图像,我认为以下内容将起到作用或至少让您开始:
- (UIImage *) composeImageWithWidth:(NSInteger)_width andHeight:(NSInteger)_height {
CGSize _size = CGSizeMake(_width, _height);
UIGraphicsBeginImageContext(_size);
// Draw image with Quartz 2D routines over here...
UIImage *_compositeImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return _compositeImage;
}
//
// cf. https://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/FilesandNetworking/FilesandNetworking.html#//apple_ref/doc/uid/TP40007072-CH21-SW20
//
- (BOOL) writeApplicationData:(NSData *)data toFile:(NSString *)fileName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if (!documentsDirectory) {
NSLog(@"Documents directory not found!");
return NO;
}
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
return ([data writeToFile:appFile atomically:YES]);
}
// ...
NSString *_imageName = @"myImageName.png";
NSData *_imageData = [NSData dataWithData:UIImagePNGRepresentation([self composeImageWithWidth:100 andHeight:100)];
if (![self writeApplicationData:_imageData toFile:_imageName]) {
NSLog(@"Save failed!");
}
在Swift 5中:
func pngFrom(image: UIImage) -> UIImage {
let imageData = image.pngData()!
let imagePng = UIImage(data: imageData)!
return imagePng
}
我创建了一个UIImage的扩展,实现了安全解包:
扩展
extension UIImage {
func toPNG() -> UIImage? {
guard let imageData = self.pngData() else {return nil}
guard let imagePng = UIImage(data: imageData) else {return nil}
return imagePng
}
}
用法:
let image = //your UIImage
if let pngImage = image.toPNG() {
UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil)
}
extension UIImage {
func saveToPhotos(completion: @escaping (_ success:Bool) -> ()) {
if let pngData = self.pngData() {
PHPhotoLibrary.shared().performChanges({ () -> Void in
let creationRequest = PHAssetCreationRequest.forAsset()
let options = PHAssetResourceCreationOptions()
creationRequest.addResource(with: PHAssetResourceType.photo, data: pngData, options: options)
}, completionHandler: { (success, error) -> Void in
if success == false {
if let errorString = error?.localizedDescription {
print("Photo could not be saved: \(errorString))")
}
completion(false)
}
else {
print("Photo saved!")
completion(true)
}
})
}
else {
completion(false)
}
}
}
使用方法:
if let image = UIImage(named: "Background.png") {
image.saveToPhotos { (success) in
if success {
// image saved to photos
}
else {
// image not saved
}
}
}
UIImageWriteToSavedPhotosAlbum
一起使用,无需保存到文档文件夹。 - Jonny