【问题标题】:How to Save UIImage to a Transparent PNG?如何将 UIImage 保存为透明的 PNG?
【发布时间】:2015-04-17 04:47:50
【问题描述】:

我不确定我在哪里做错了,这就是为什么我想在这里粘贴一些代码块以找出问题所在。

我有一些具有透明背景的 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"];
    }
}

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

最后,这就是我从 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]];
}

以及从 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;
}

我不知道我在哪里做错了,但一如既往,当我选择具有透明背景的图像时。它总是将其背景转换为白色。我需要保存它,因为它是透明的。我已经搜索了很多,但找不到任何解决此问题的方法。

感谢任何帮助。

【问题讨论】:

  • 嗯...似乎您在获取图像时专门提取了数据。我会在几秒钟内写一个建议。
  • 实际上,“测试”图像不透明?好像您的代码是正确的...您确定按钮的背景清晰吗?我还建议将您的图像放在 UIImageView 中进行测试,以检查透明度。
  • @LyndseyScott 感谢您的回复。我需要提到的是,我相信在我选择后保存图像时会出现问题,因为在保存后,为了确保我去检查我的应用程序文件夹中的内容。如果所选图像是透明的,则其背景变为白色。如果选择了不透明,那么它的工作正常。因此,我的问题是我没有得到我选择的内容。
  • 但是你怎么能通过查看应用程序文件夹中的图像来判断它不是透明的呢?当您只查看文件时,即使图像是透明的,背景也会显示为白色,因为图像必须显示在某物上并且不能只是漂浮在空间中。
  • 原始图像在透明背景上有白色徽标文字。根据我正在检查的 NSUserDefault 可能性,如果“logoImageData”不存在作为值,我将调用原始徽标图像并将其放在 UIBarButtonItem 上。但是,如果“logoImageData”作为一个值存在,那么保存在应用目录中的图像就会被调用。顺便说一句,我在两种方法中都使用了相同的图像。但是保存的图像变成全白色,当我将它放在黑色 UIBarButtonItem 上时,它不会显示白色徽标文本。只是全白。

标签: ios objective-c uiimage png transparent


【解决方案1】:

问题解决了!

我随问题发布的代码块没有任何问题。问题出现在 iTunes 中,当我将 Mac 中的图像同步到我的 iPhone iTunes 时,将它们转换为 JPEG,因此图像失去了透明度等......当我使用我的应用程序选择图像时,我选择它们为 JPEG 没有意识到这就是我遇到这些问题的原因。

所以我想出了一个通过电子邮件获取图像的解决方案。我只是通过电子邮件将它们从我的 mac 发送到 iPhone,并且通过这些图像并没有丢失任何功能。之后,当我在应用程序中将它们用作正确的图像时,程序按预期运行。

【讨论】:

  • 我们也可以在模拟器中测试PNG文件。我们可以将 png 图像从“Finder”直接拖放到模拟器中的“照片”应用程序中。这些图像从我们应用程序中的图像选择器返回为具有透明度的正确 png 图像。
【解决方案2】:

你写的

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

但我看不到你在哪里同步。所以添加:

      [logoUserDef synchronize];

【讨论】:

  • 我将添加它以查看更改。我会告诉你结果。谢谢
  • 我已经测试过了。添加[logoUserDef synchronize]; 没有任何区别。代码仍在将透明背景转换为白色。
【解决方案3】:

使用后将图像保存到 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 等其他选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-11
    • 2023-03-08
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 2014-08-09
    • 2015-06-24
    • 1970-01-01
    相关资源
    最近更新 更多