如何将 UIImage 保存为透明 PNG?
How to Save UIImage to a Transparent PNG?
我不确定我在哪里做错了,这就是为什么我想在这里粘贴一些代码块以找出问题所在。
我有一些具有透明背景的 PNG 图像,使用下面的代码块我正在尝试将 selected 图像保存到应用程序文件夹和 NSUserDefault。然后我试图从应用程序文件夹中调用保存的图像并显示在 UIBarButtonItem 上。
保存到NSUserDefault也是为了测试
所以,
这就是我select拍摄图像的方式。
- (IBAction)btnPressed:(UIButton *)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.delegate = self;
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imgPicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
imgPicker.allowsEditing = NO;
[self presentViewController:imgPicker animated:YES completion:nil];
}
}
然后我使用 didFinishPickingMediaWithInfo;
将其保存到应用程序
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *) kUTTypeImage])
{
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
//I believe this has the problem.
NSData *pngData = UIImagePNGRepresentation(image);
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:@"AppImages"];;
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath])
[[NSFileManager defaultManager] createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *fileName = [stringPath stringByAppendingPathComponent:@"logoImage.png"];
[pngData writeToFile:fileName atomically:YES];
NSUserDefaults *logoUserDef = [NSUserDefaults standardUserDefaults];
[logoUserDef setValue:pngData forKey:@"logoImageData"];
}
}
注意:我对没有透明背景的图像没有问题。
最后,这就是我从 Application 和 NSUserDefault 调用它的方式。
同时使用 NSUserDefaults 和 AppDirectory 查看它们是否显示不同的结果。
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"logoImageData"])
{
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
UIImage *testing = [UIImage imageWithData:[user valueForKey:@"logoImageData"]];
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * image = [self loadImageWithFileName:@"logoImage" ofType:@"png" inDirectory:documentsDirectory];
UIBarButtonItem *logoBarButton = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(logoTapped)];
logoBarButton.imageInsets = UIEdgeInsetsMake(9, 0, 9, 90);
logoBarButton.image = [logoBarButton.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[self.navigationItem setLeftBarButtonItems:@[logoBarButton]];
}
以及 returns 来自 App Document 的 UIImage 的方法。
-(UIImage *)loadImageWithFileName:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/%@.%@", directoryPath, @"AppImages", fileName, [extension lowercaseString]]];
return result;
}
我不知道我哪里做错了,但一如既往,当我 select 具有透明背景的图像时。它总是将其背景转换为白色。我需要保存它,因为它是透明的。我搜索了很多,但找不到解决这个问题的方法。
感谢任何帮助。
你写了
[logoUserDef setValue:pngData forKey:@"logoImageData"];
但我没看到你在哪里同步。所以添加:
[logoUserDef synchronize];
问题解决了!
我随问题发布的代码块没有任何问题。问题是从 iTunes 发生的,当我将图像从 Mac 同步到我的 iPhone iTunes 将它们转换为 JPEG 并且由于此图像失去透明度等......当我 select使用我的应用程序时,我 select 在不知情的情况下将它们转换为 JPEG,这就是我遇到这些问题的原因。
所以我想出了一个通过电子邮件获取图像的解决方案。我只是通过电子邮件将它们从我的 mac 发送到 iPhone,并且通过这些图像并没有丢失任何功能。在那之后,当我在应用程序中将它们用作正确的图像时,程序按预期运行。
我在使用
后将图像保存到 Documents 目录时能够保留透明度
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[self dismissViewControllerAnimated:YES completion:nil];
UIImage *img = [info valueForKey:UIImagePickerControllerOriginalImage];
[yourButton setImage:img forState:UIControlStateNormal];
NSData *pngData = UIImagePNGRepresentation(img);
//do something with pngData
}
关键是 UIImagePickerControllerOriginalImage 而不是其他选项,如 UIImagePickerControllerEditedImage。
我不确定我在哪里做错了,这就是为什么我想在这里粘贴一些代码块以找出问题所在。
我有一些具有透明背景的 PNG 图像,使用下面的代码块我正在尝试将 selected 图像保存到应用程序文件夹和 NSUserDefault。然后我试图从应用程序文件夹中调用保存的图像并显示在 UIBarButtonItem 上。
保存到NSUserDefault也是为了测试
所以,
这就是我select拍摄图像的方式。
- (IBAction)btnPressed:(UIButton *)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.delegate = self;
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imgPicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
imgPicker.allowsEditing = NO;
[self presentViewController:imgPicker animated:YES completion:nil];
}
}
然后我使用 didFinishPickingMediaWithInfo;
将其保存到应用程序-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *) kUTTypeImage])
{
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
//I believe this has the problem.
NSData *pngData = UIImagePNGRepresentation(image);
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:@"AppImages"];;
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath])
[[NSFileManager defaultManager] createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *fileName = [stringPath stringByAppendingPathComponent:@"logoImage.png"];
[pngData writeToFile:fileName atomically:YES];
NSUserDefaults *logoUserDef = [NSUserDefaults standardUserDefaults];
[logoUserDef setValue:pngData forKey:@"logoImageData"];
}
}
注意:我对没有透明背景的图像没有问题。
最后,这就是我从 Application 和 NSUserDefault 调用它的方式。
同时使用 NSUserDefaults 和 AppDirectory 查看它们是否显示不同的结果。
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"logoImageData"])
{
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
UIImage *testing = [UIImage imageWithData:[user valueForKey:@"logoImageData"]];
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * image = [self loadImageWithFileName:@"logoImage" ofType:@"png" inDirectory:documentsDirectory];
UIBarButtonItem *logoBarButton = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(logoTapped)];
logoBarButton.imageInsets = UIEdgeInsetsMake(9, 0, 9, 90);
logoBarButton.image = [logoBarButton.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[self.navigationItem setLeftBarButtonItems:@[logoBarButton]];
}
以及 returns 来自 App Document 的 UIImage 的方法。
-(UIImage *)loadImageWithFileName:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/%@.%@", directoryPath, @"AppImages", fileName, [extension lowercaseString]]];
return result;
}
我不知道我哪里做错了,但一如既往,当我 select 具有透明背景的图像时。它总是将其背景转换为白色。我需要保存它,因为它是透明的。我搜索了很多,但找不到解决这个问题的方法。
感谢任何帮助。
你写了
[logoUserDef setValue:pngData forKey:@"logoImageData"];
但我没看到你在哪里同步。所以添加:
[logoUserDef synchronize];
问题解决了!
我随问题发布的代码块没有任何问题。问题是从 iTunes 发生的,当我将图像从 Mac 同步到我的 iPhone iTunes 将它们转换为 JPEG 并且由于此图像失去透明度等......当我 select使用我的应用程序时,我 select 在不知情的情况下将它们转换为 JPEG,这就是我遇到这些问题的原因。
所以我想出了一个通过电子邮件获取图像的解决方案。我只是通过电子邮件将它们从我的 mac 发送到 iPhone,并且通过这些图像并没有丢失任何功能。在那之后,当我在应用程序中将它们用作正确的图像时,程序按预期运行。
我在使用
后将图像保存到 Documents 目录时能够保留透明度- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[self dismissViewControllerAnimated:YES completion:nil];
UIImage *img = [info valueForKey:UIImagePickerControllerOriginalImage];
[yourButton setImage:img forState:UIControlStateNormal];
NSData *pngData = UIImagePNGRepresentation(img);
//do something with pngData
}
关键是 UIImagePickerControllerOriginalImage 而不是其他选项,如 UIImagePickerControllerEditedImage。