如何将UIImage保存为透明的PNG格式?

3

我不确定我的错误在哪里,所以我想在这里粘贴一些代码块,以便找出问题所在。

我有一些带有透明背景的PNG图像,使用以下代码块,我尝试将选定的图像保存到应用程序文件夹和NSUserDefault中。然后,我尝试从应用程序文件夹调用保存的图像,并在UIBarButtonItem上显示。

同时保存到NSUserDefault是为了测试目的。

所以,

这是我如何选择图像。

- (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"];
    }
}

注意:我不会对没有透明背景的图像产生问题。

最后,这是我从应用程序和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]];
}

从应用程序文档返回UIImage的方法。

-(UIImage *)loadImageWithFileName:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
    UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/%@.%@",   directoryPath, @"AppImages", fileName, [extension lowercaseString]]];

    return result;
}

我不知道我哪里出了问题,但通常情况下,当我选择具有透明背景的图像时,它总是将其背景转换为白色。我需要将其保存为透明的状态。我已经搜索了很多,但是找不到解决方法。

希望能得到任何帮助。


@LyndseyScott 谢谢您的回复。我需要提到,我相信问题出现在我选择后保存图像时,因为保存后,为了确保我所拥有的内容,我会去检查我的应用程序文件夹中的内容。如果选择的图像是透明的,则其背景变为白色。如果选择的是非透明的,则一切正常。因此,我的问题是我没有得到我选择的内容。 - Yusuf
但是仅仅通过查看应用程序文件夹中的图像,你怎么能确定它不是透明的呢?当你只查看文件时,背景会显示为白色,即使图像是透明的,因为图像必须显示在某些东西上,而不能漂浮在空中。 - Lyndsey Scott
事情是这样的...我问你的“testing”图像是否正确,因为你正在以正确的方式检索它。至于“image”,似乎不是这样。所以我再问一遍,你确定“testing”也不是透明的吗?还是只有“image”不透明? - Lyndsey Scott
抱歉回复晚了,@LyndseyScott。我已经检查了你要求我的所有内容。"testing"是透明图像。我在UIImageView上测试了保存的图像,结果与UIBarButtonItem上的相同。120x44尺寸变成全白。但为了确保,我还在UIImageView上测试了原始图像,它可以正常工作。顺便说一句,在开始测试之前,我将UIImageView背景设置为黑色,以查看白色标志文本,但只在我的原始图像上看到了它。我真的不知道我还应该做什么来解决这个问题。显然,现在出现了保存问题。 - Yusuf
我想感谢@LyndseyScott,没有你的指导,我就找不到问题出在哪里了。再次感谢你。/鞠躬 - Yusuf
显示剩余6条评论
3个回答

1

问题已解决!

我在问题中发布的代码块没有任何问题。问题出现在iTunes上,当我将图片从Mac同步到iPhone时,iTunes将它们转换为JPEG格式,因此图片失去了透明度等特性... 当我使用我的应用程序选择图片时,我选择它们作为JPEG格式而不知道这一点,这就是我遇到这些问题的原因。

因此,我想出了一个解决方案,即通过电子邮件获取图像。我只需将它们从我的Mac发送到iPhone的电子邮件中,这样图片不会失去任何特性。之后,当我将它们作为正确的图像在应用程序中使用时,程序按照预期工作。


我们也可以在模拟器中测试PNG文件。我们可以直接从“Finder”将png图像拖放到模拟器中的“照片”应用程序中。这些图像将作为透明的正确png图像从我们应用程序中的图像选择器返回。 - SHS

0

你写了

     [logoUserDef setValue:pngData forKey:@"logoImageData"];

但我没有看到你在哪里进行同步。所以请添加:

      [logoUserDef synchronize];

我会添加这个以查看更改。我会通知您结果。谢谢。 - Yusuf
我已经测试过了。添加 [logoUserDef synchronize]; 没有任何区别。代码仍然将透明背景转换为白色。 - Yusuf

0

在使用后,我能够将图像保存到文档目录并保留透明度。

- (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。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接