2011-10-20 14 views
32

używam następujący kod, aby zapisać i załadować zdjęcia, które mam wybrać z każdej biblioteki lub podjąć korzystania z aparatu:Zapisz UIImage, załaduj go w nieprawidłowym kierunku

//saving an image 
- (void)saveImage:(UIImage*)image:(NSString*)imageName { 
    NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format. 
    NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it 
    NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory 
    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]]; //add our image to the path 
    [fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image) 
    NSLog(@"image saved"); 
} 

//loading an image 
- (UIImage*)loadImage:(NSString*)imageName { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]]; 
    return [UIImage imageWithContentsOfFile:fullPath]; 
} 

ten sposób ustawić zbierane wizerunek mają być pokazane w moim UIImageView:

imgView.image = [info objectForKey:@"UIImagePickerControllerOriginalImage"]; 

jednak, kiedy mogę odebrać i obraz i ustawić go pokazać w moim UIImageView to jest w porządku, ale kiedy załadować ten obraz często jest niewłaściwa orientacja. Jakieś pomysły? Ktoś to doświadczył lub wiedział, jak rozwiązać ten problem?

Dzięki.

EDIT:

Wydaje się więc, jeśli załadować zdjęcie, które zostało zrobione zdjęcie w układzie pionowym do góry nogami, to ładuje w tym kierunku, jeśli wziąć zdjęcie w krajobrazie lewo ładuje w tym kierunku. Wszelkie pomysły, jak sobie z tym poradzić? Niezależnie od orientacji, którą ładują, zawsze zwracają jako UIImageOrientationUp.

+0

Wystarczy spojrzeć na UIImageOrientationUp dla dokumentacji UIImage. możesz ustawić właściwość dla imageOrientation obiektu UIImage. –

+0

Jak jednak zastosować tę orientację? Przyjrzałem się i wydaje mi się, że jest to tylko dla porównań, a rotacja musi być wykonana ręcznie. –

+0

Sprawdź moją edycję. –

Odpowiedz

25

Mam w obliczu podobnych problemów i oto jak ja rozwiązany to.

Chociaż zapisać obraz musimy zapisać swoje informacje orientacji wraz z obrazem ...

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
[userDefaults setInteger:[myImage imageOrientation] forKey:@"kImageOrientation"]; 
[imageOrientation release]; 

I załadować obraz musimy czytać swoje informacje orientacji i stosować go z obrazem ...

UIImage *tempImage = [[UIImage alloc] initWithContentsOfFile:fullPath]; 
UIImage *orientedImage= [[UIImage alloc] initWithCGImage: tempImage.CGImage scale:1.0 orientation:imageOrientation]; 
[tempImage release]; 

orientedImage jest wh w razie potrzeby.

Dzięki,

+0

Czy to działa, nawet po przekonwertowaniu UIImage na NSData iz powrotem? – zakdances

+0

Dziękuję, miałem problemy z dziwnymi obrotami przez 6 godzin, kiedy w końcu znalazłem tę odpowiedź. –

+1

Rozwiązało to mój problem, ale tylko raz zacząłem używać atrybutu orientacji ALAsset zamiast atrybutu UIImage. –

0

Spróbuj również zapisać orientację obrazu, a następnie po załadowaniu tego obrazu sprawdź, czy jest to poprawna orientacja, a jeśli nie, obróć obraz za pomocą CGAffineTransform lub cokolwiek chcesz.

3

Sprawdź informacje EXIF ​​dla obrazu, który ładujesz, powinien być znacznik do orientacji. Użyj wartości, aby obrócić obraz do właściwej orientacji.

Ta strona powinna Cię uruchomić.

http://www.impulseadventure.com/photo/exif-orientation.html

(Aplikacja użyłeś aby wyświetlić zdjęcie musi mieć ten wbudowany, dlatego widać prawidłową orientację podczas otwierania zdjęciu)

+1

Ahh bardzo interesujące, jednak jak chciałbym pobrać dane orientacyjne exif? –

47

Przyczyną jest PNG nie posiada informacji o orientacji obrazu, ale w formacie JPEG robi. Najłatwiejszym sposobem rozwiązania tego problemu jest zapisanie pliku w formacie JPEG przy użyciu UIImageJPEGRepresentation()

+0

To rozwiązało mój problem z zapisanymi obrazami, które nie powracają w prawidłowej orientacji - szczególnie te pobrane z aparatu. Jedyną wadą korzystania z opcji JPEG jest to, że przezroczystość nie jest zachowana, prawda? – micnguyen

1

Możesz użyć Image I/O, aby zapisać obraz PNG do pliku (lub NSMutableData) w odniesieniu do orientacji oryginalnego obrazu. W poniższym przykładzie zapisuję obraz PNG do pliku pod numerem path.

- (BOOL)savePngFile:(UIImage *)image toPath:(NSString *)path { 
    NSData *data = UIImagePNGRepresentation(image); 
    int exifOrientation = [UIImage cc_iOSOrientationToExifOrientation:image.imageOrientation]; 
    NSDictionary *metadata = @{(__bridge id)kCGImagePropertyOrientation:@(exifOrientation)}; 
    NSURL *url = [NSURL fileURLWithPath:path]; 
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); 
    if (!source) { 
     return NO; 
    } 
    CFStringRef UTI = CGImageSourceGetType(source); 
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, UTI, 1, NULL); 
    if (!destination) { 
     CFRelease(source); 
     return NO; 
    } 
    CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)metadata); 
    BOOL success = CGImageDestinationFinalize(destination); 
    CFRelease(destination); 
    CFRelease(source); 
    return success; 
} 

cc_iOSOrientationToExifOrientation: to metoda UIImage kategorii.

+ (int)cc_iOSOrientationToExifOrientation:(UIImageOrientation)iOSOrientation { 
    int exifOrientation = -1; 
    switch (iOSOrientation) { 
     case UIImageOrientationUp: 
      exifOrientation = 1; 
      break; 

     case UIImageOrientationDown: 
      exifOrientation = 3; 
      break; 

     case UIImageOrientationLeft: 
      exifOrientation = 8; 
      break; 

     case UIImageOrientationRight: 
      exifOrientation = 6; 
      break; 

     case UIImageOrientationUpMirrored: 
      exifOrientation = 2; 
      break; 

     case UIImageOrientationDownMirrored: 
      exifOrientation = 4; 
      break; 

     case UIImageOrientationLeftMirrored: 
      exifOrientation = 5; 
      break; 

     case UIImageOrientationRightMirrored: 
      exifOrientation = 7; 
      break; 

     default: 
      exifOrientation = -1; 
    } 
    return exifOrientation; 
} 

alternatywnie można zapisać obraz do NSMutableData użyciu CGImageDestinationCreateWithData i przekazać NSMutableData zamiast NSURL w CGImageDestinationCreateWithURL.

Powiązane problemy