0

我試圖加載一個帶有透明背景的PNG文件到一個UIImageView中(如果它很重要,用Objective C,XCode 8.0開發IOS 10.0目標)。 當顯示在UIImageView中時,圖像的背景顏色顯示爲黑色(見下文)。iOS Objective C加載一個帶有透明背景的PNG文件到一個UIImageView

如何將任意PNG文件加載到UIImageView,使其透明背景被保留?

奇怪的是,我的應用程序資產中有透明背景的PNG圖像,並且它們顯示在UIImageView中,沒有任何額外的混亂。

請注意在下面的代碼中,我嘗試過的一件事是重建從imagePicker(請參閱imageWithImage)傳遞的UIImage,爲新圖像設置新的圖形上下文。我曾經在某些帖子中看到過這種方法,它們涉及到模糊的類似問題,但它不起作用(更不用說,似乎愚蠢的IOS會要求它支持加載映像中定義的透明度)。

的PNG圖像我與測試是一個標準的PNG32(從互聯網上用於測試目的收穫 - 注意,我已經嘗試了許多其他圖片):

enter image description here

左下圖顯示之前的應用程序屏幕加載上面的圖片,右鍵顯示加載的圖片: enter image description here

PNG圖片文件是通過點擊屏幕底部的'select image'打開的imagePicker來選擇的。

我的視圖控制器代碼:

// 
// ViewController.m 
// ImageTest 
// 

#import "ViewController.h" 
#import "MobileCoreServices/MobileCoreServices.h" 


#define FONT_SIZE_BUTTON 32 

@interface ViewController() 

@end 

@implementation ViewController 

UIImageView *myImageView; 
UIImage *myImage; 
UIButton *btnSelect; 

- (void)viewDidLoad { 

    NSLog(@"viewDidLoad"); 

    [super viewDidLoad]; 

    CGRect screenRect = [[UIScreen mainScreen] bounds]; 

    CGFloat btnHeight = 40; 
    CGFloat btnMargin = 10; 
    CGFloat btnWidth = screenRect.size.width - 2*btnMargin; 
    CGFloat btnULY = screenRect.size.height - btnHeight - 2*btnMargin; 

    btnSelect = [[UIButton alloc] initWithFrame:CGRectMake(btnMargin, btnULY, btnWidth, btnHeight)]; 
    [btnSelect.titleLabel setFont:[UIFont boldSystemFontOfSize:FONT_SIZE_BUTTON]]; 
    [btnSelect setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; 
    [btnSelect setTitle :@"Select Image" forState:UIControlStateNormal]; 
    [btnSelect.layer setBorderWidth:4.0f]; 
    [btnSelect.layer setBorderColor:[UIColor blueColor].CGColor]; 
    [btnSelect setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 
    [btnSelect setTitleColor:[UIColor grayColor] forState:UIControlStateSelected]; 
    [btnSelect setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled]; 
    btnSelect.backgroundColor = [UIColor whiteColor]; 
    btnSelect.tag = 4200; 
    [btnSelect addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside]; 
    btnSelect.userInteractionEnabled = true; 

    CGFloat ulx = 10; 
    CGFloat uly = 20; 
    CGFloat width = screenRect.size.width - 2*ulx; 
    CGFloat height = width * 9.0/16.0; 

    CGRect imageFrame = CGRectMake(ulx, uly, width, height); 

    myImageView = [[UIImageView alloc] initWithFrame:imageFrame]; 
    myImageView.alpha = 1.0f; 
    myImageView.backgroundColor = [UIColor lightGrayColor]; 
    myImageView.contentMode = UIViewContentModeScaleAspectFit; 

    myImageView.opaque = false; 
    [[myImageView layer] setOpaque:false]; 

    [[myImageView layer] setBorderWidth:4.0f]; 
    [[myImageView layer] setBorderColor:[UIColor redColor].CGColor]; 

    // Add elements to this view controller 
    [self.view addSubview:myImageView]; 
    [self.view addSubview:btnSelect]; 
} 


- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 


// Ensure image is opened honoring transparency of PNGs 
- (UIImage *)imageWithImage:(UIImage *)image { 
    CGSize newSize = image.size; 
    CGRect newRect = CGRectMake(0,0,newSize.width, newSize.height); 

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 1.0); 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    [[UIColor clearColor] set]; 
    CGContextFillRect(ctx, newRect); 

    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.Height)]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
#pragma mark - Select Actions 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- (IBAction)onClick: (UIButton *)btn 
{ 
    NSLog(@"onClick"); 
    // DDLogInfo(@"%@:%@", THIS_FILE, THIS_METHOD); 

    UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 
    picker.delegate = self; 
    picker.allowsEditing = YES; 
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 
    NSMutableArray *mediaTypes = [[NSMutableArray alloc] init]; 
    [mediaTypes addObject:(__bridge NSString *)kUTTypeImage]; 
    picker.mediaTypes = mediaTypes; 

    [self presentViewController:picker animated:YES completion:NULL]; 
} 


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
#pragma mark - UIImagePicker's Delegate 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 

    NSLog(@"imagePickerController"); 

    UIImage *chosenImage = [self imageWithImage:info[UIImagePickerControllerEditedImage]]; 
// UIImage *chosenImage = info[UIImagePickerControllerEditedImage]; 
// UIImage *chosenImage = [info[UIImagePickerControllerEditedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 
    if (myImageView != nil) 
     myImageView.image = chosenImage; 

    myImage = chosenImage; 

    [picker dismissViewControllerAnimated:YES completion:NULL]; 
} 



- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { 

    [picker dismissViewControllerAnimated:YES completion:NULL]; 
} 


@end 

**

與Final修復編輯

**

更新後的應用屏幕的截屏顯示問題:

enter image description here

和最終(固定)的代碼,顯示使用字典的鍵(UIImagePickerControllerOriginalImage)和字典鍵(UIImagePickerControllerEditedImage)之間的區別:

// 
// ViewController.m 
// ImageTest 
// 
// Created by Robb Main on 2016-11-21. 
// Copyright © 2016 Robb Main. All rights reserved. 
// 

#import "ViewController.h" 
#import "MobileCoreServices/MobileCoreServices.h" 


#define FONT_SIZE_BUTTON 32 

@interface ViewController() 

@end 

@implementation ViewController 

UIImageView *myImageView1; 
UIImageView *myImageView2; 
UIImageView *myImageView3; 
UIImage *myImage; 
UIButton *btnSelect; 

- (void)viewDidLoad { 

    NSLog(@"viewDidLoad"); 

    [super viewDidLoad]; 

    CGRect screenRect = [[UIScreen mainScreen] bounds]; 

    CGFloat btnHeight = 40; 
    CGFloat btnMargin = 10; 
    CGFloat btnWidth = screenRect.size.width - 2*btnMargin; 
    CGFloat btnULY = screenRect.size.height - btnHeight - 2*btnMargin; 

    btnSelect = [[UIButton alloc] initWithFrame:CGRectMake(btnMargin, btnULY, btnWidth, btnHeight)]; 
    [btnSelect.titleLabel setFont:[UIFont boldSystemFontOfSize:FONT_SIZE_BUTTON]]; 
    [btnSelect setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; 
    [btnSelect setTitle :@"Select Image" forState:UIControlStateNormal]; 
    [btnSelect.layer setBorderWidth:4.0f]; 
    [btnSelect.layer setBorderColor:[UIColor blueColor].CGColor]; 
    [btnSelect setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 
    [btnSelect setTitleColor:[UIColor grayColor] forState:UIControlStateSelected]; 
    [btnSelect setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled]; 
    btnSelect.backgroundColor = [UIColor whiteColor]; 
    btnSelect.tag = 4200; 
    [btnSelect addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside]; 
    btnSelect.userInteractionEnabled = true; 

    CGFloat imgMargin = 60; 
    CGFloat ulx = imgMargin; 
    CGFloat uly = 20; 
    CGFloat imgWidth = screenRect.size.width - 2*imgMargin; 
    CGFloat imgHeight = imgWidth * 9.0/16.0; 

    CGRect imageFrame = CGRectMake(ulx, uly, imgWidth, imgHeight); 

    myImageView1 = [[UIImageView alloc] initWithFrame:imageFrame]; 
    myImageView1.alpha = 1.0f; 
    myImageView1.backgroundColor = [UIColor lightGrayColor]; 
    myImageView1.contentMode = UIViewContentModeScaleAspectFit; 
    myImageView1.opaque = NO; 
    [myImageView1.layer setOpaque:NO]; 
// myImageView.clearsContextBeforeDrawing = YES; 
    [myImageView1.layer setBorderWidth:4.0f]; 
    [myImageView1.layer setBorderColor:[UIColor redColor].CGColor]; 

    myImageView1.image = [UIImage imageNamed:@"imageTest.png"]; 

    uly += imgHeight+8; 
    CGFloat lblHeight = 10; 
    CGRect lblFrame = CGRectMake(ulx, uly, imgWidth, lblHeight); 
    UILabel *myLabel1 = [[UILabel alloc] initWithFrame:lblFrame]; 
    [myLabel1 setFont:[UIFont systemFontOfSize:12]]; 
    myLabel1.text = @"PNG Image from assets"; 

    uly += lblHeight+20; 
    imageFrame.origin.y = uly; 

    myImageView2 = [[UIImageView alloc] initWithFrame:imageFrame]; 
    myImageView2.alpha = 1.0f; 
    myImageView2.backgroundColor = [UIColor lightGrayColor]; 
    myImageView2.contentMode = UIViewContentModeScaleAspectFit; 
    myImageView2.opaque = NO; 
    [myImageView2.layer setOpaque:NO]; 
// myImageView2.clearsContextBeforeDrawing = YES; 
    [myImageView2.layer setBorderWidth:4.0f]; 
    [myImageView2.layer setBorderColor:[UIColor redColor].CGColor]; 

    uly += imgHeight+8; 
    lblFrame.origin.y = uly; 

    UILabel *myLabel2 = [[UILabel alloc] initWithFrame:lblFrame]; 
    [myLabel2 setFont:[UIFont systemFontOfSize:12]]; 
    myLabel2.text = @"UIImagePickerControllerOriginalImage"; 

    uly += lblHeight+20; 
    imageFrame.origin.y = uly; 

    myImageView3 = [[UIImageView alloc] initWithFrame:imageFrame]; 
    myImageView3.alpha = 1.0f; 
    myImageView3.backgroundColor = [UIColor lightGrayColor]; 
    myImageView3.contentMode = UIViewContentModeScaleAspectFit; 
    myImageView3.opaque = NO; 
    [myImageView3.layer setOpaque:NO]; 
// myImageView3.clearsContextBeforeDrawing = YES; 
    [myImageView3.layer setBorderWidth:4.0f]; 
    [myImageView3.layer setBorderColor:[UIColor redColor].CGColor]; 

    uly += imgHeight+8; 
    lblFrame.origin.y = uly; 

    UILabel *myLabel3 = [[UILabel alloc] initWithFrame:lblFrame]; 
    [myLabel3 setFont:[UIFont systemFontOfSize:12]]; 
    myLabel3.text = @"UIImagePickerControllerEditedImage"; 

    // Add elements to this view controller 
    [self.view addSubview:myImageView1]; 
    [self.view addSubview:myLabel1]; 
    [self.view addSubview:myImageView2]; 
    [self.view addSubview:myLabel2]; 
    [self.view addSubview:myImageView3]; 
    [self.view addSubview:myLabel3]; 
    [self.view addSubview:btnSelect]; 
} 


- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
#pragma mark - Select Actions 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- (IBAction)onClick: (UIButton *)btn 
{ 
    NSLog(@"onClick"); 
    // DDLogInfo(@"%@:%@", THIS_FILE, THIS_METHOD); 

    UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 
    picker.delegate = self; 
    picker.allowsEditing = NO; 
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 
    NSMutableArray *mediaTypes = [[NSMutableArray alloc] init]; 
    [mediaTypes addObject:(__bridge NSString *)kUTTypeImage]; 
    picker.mediaTypes = mediaTypes; 

    [self presentViewController:picker animated:YES completion:NULL]; 
} 


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
#pragma mark - UIImagePicker's Delegate 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 

    NSLog(@"imagePickerController"); 

    myImage = info[UIImagePickerControllerOriginalImage]; 
    if (myImageView2 != nil) 
     myImageView2.image = myImage; 

    if (myImageView3 != nil) 
     myImageView3.image = info[UIImagePickerControllerEditedImage]; 

    [picker dismissViewControllerAnimated:YES completion:NULL]; 
} 



- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { 

    [picker dismissViewControllerAnimated:YES completion:NULL]; 
} 


@end 

這工作,雖然目前還不清楚我爲什麼:

  1. imagePicker不會爲無效的字典鍵返回nil(我指定了編輯是不允許的)。

  2. '編輯'圖像會去除透明度信息。

+0

你的'imageWithImage:'方法有什麼意義?爲什麼不直接在圖像視圖中使用選定的圖像?爲什麼使用'UIImagePickerControllerEditedImage'而不是'UIImagePickerControllerOriginalImage'? – rmaddy

+0

謝謝,馬迪。我imageWithImage:方法_is_真的毫無意義。我在嘗試解決問題的選項時實施了它。然而,你的其他建議做到了。使用UIImagePickerControllerOriginalImage作爲詞典鍵顯示圖像應該是。我將添加最終代碼和屏幕截圖來完成此操作。請提交答案,以便我可以接受。 – gOnZo

回答

0

您的主要問題是在獲取所選圖像時,使用UIImagePickerControllerEditedImage而不是UIImagePickerControllerOriginalImage。編輯的圖像失去了alpha通道,導致黑色而不是透明度。

您也不需要imageWithImage:方法。

+0

謝謝,Maddy。這解決了我的問題。 – gOnZo