Как получить оригинальное имя файла фотографии в iOS? - PullRequest
15 голосов
/ 24 августа 2011

В настоящее время я разрабатываю приложение для iPad, в котором пользователь вводит имя файла фотографии в текстовое поле (как часть примечаний к полю), а затем импортирует свои фотографии в библиотеку фотографий iPad.Приложение получит доступ к библиотеке, используя ALAssetsLibrary, и будет перечислять фотографии, ища те с именем файла, которое они указали в своих примечаниях к полю.Это было бы имя файла, данное фотографии камерой, которая его сделала.Например, "DSC_0019.JPG".

Разве это невозможно?

Я заметил, что, если я импортирую фотографии с моей камеры на iPad, затем откройте iPhoto на моем Mac и посмотрите на iPad как на камеру, я могу "получить информацию"на изображениях, хранящихся на iPad, и посмотрите оригинальное имя файла, которое я ищу.Однако это не содержится в метаданных на iPad.

Любая помощь будет принята с благодарностью.

Вот мой код:

(При работе с CFDictionary практически все равно нулю, кроме клавиш Exif, которые не имеют того, что я ищу)

- (void)viewDidLoad
{
    [super viewDidLoad];

    //start activity animation
    [self.activity setHidden:NO];
    [self.activity startAnimating];

    //init our arrays
    autoAssignedAssets  = [[NSMutableArray alloc] init];
    unAssignedRecords   = [[NSMutableArray alloc] init];
    unAssignedAssets    = [[NSMutableArray alloc] init];

    //setup the library
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];



    //[ BLOCK ] => assetEnumerator
    //
    void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {

        if (result != nil) {

            if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto] ) {


                //=================================================================

                ALAssetRepresentation* representation = [result defaultRepresentation];

                // create a buffer to hold the data for the asset's image
                uint8_t *buffer = (Byte*)malloc(representation.size);// copy the data from the asset into the buffer
                NSUInteger length = [representation getBytes:buffer fromOffset: 0.0  length:representation.size error:nil];

                // convert the buffer into a NSData object, free the buffer after
                NSData *adata = [[NSData alloc] initWithBytesNoCopy:buffer length:representation.size freeWhenDone:YES];

                // setup a dictionary with a UTI hint.  The UTI hint identifies the type of image we are dealing with (ie. a jpeg, png, or a possible RAW file)
                // specify the source hint
                NSDictionary* sourceOptionsDict = [NSDictionary dictionaryWithObjectsAndKeys: (id)[representation UTI] ,kCGImageSourceTypeIdentifierHint, nil];


                // create a CGImageSource with the NSData.  A image source can contain x number of thumbnails and full images.
                CGImageSourceRef sourceRef = CGImageSourceCreateWithData((CFDataRef) adata,  (CFDictionaryRef) sourceOptionsDict);

                [adata release];

                CFDictionaryRef imagePropertiesDictionary;

                // get a copy of the image properties from the CGImageSourceRef
                imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(sourceRef,0, NULL);

                //NSString *imageFilename = (NSString*)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyCIFFImageFileName);

                NSLog(@"%@", (NSDictionary *)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyExifDictionary));

                CFNumberRef imageWidth = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelWidth);
                CFNumberRef imageHeight = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelHeight);

                int w = 0;
                int h = 0;

                CFNumberGetValue(imageWidth, kCFNumberIntType, &w);
                CFNumberGetValue(imageHeight, kCFNumberIntType, &h);

                // cleanup memory
                CFRelease(imagePropertiesDictionary);
                CFRelease(sourceRef);

                //NSLog(@"width: %d, height: %d", w, h);
                //NSLog(@"%@", imageFilename);



                //=================================================================


                //NSDictionary *metadata = [[result defaultRepresentation] metadata];
                //NSLog(@"\n\nAsset Info: %@", result);
                //NSLog(@"\n\n\n\nMetaData: %@", metadata);
                [autoAssignedAssets addObject:result];

            }//end if photo

        }//end if

    }; //end assetEnumerator block



    //[ BLOCK ] => assetGroupEnumerator
    //
    void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) =  ^(ALAssetsGroup *group, BOOL *stop) {

        if(group != nil) {
            [group enumerateAssetsUsingBlock:assetEnumerator];
        }//end if


        //now we're done, reload and stop animations
        [self.tableView reloadData];
        [self.activity stopAnimating];
        [self.activity setHidden:YES];

    }; //end assetGroupEnumerator block



    //[ BLOCK ] => failureBlock
    //
    void (^failureBlock)(NSError *) = ^(NSError *error) {

        NSString *errorTitle = [error localizedDescription];
        NSString *errorMessage = [error localizedRecoverySuggestion];
        NSString *errorFailureDesc = [error localizedFailureReason];

        NSLog(@"Error: %@, Suggestion: %@, Failure desc: %@", errorTitle, errorMessage, errorFailureDesc);

    }; //end failureBlock




    //loop over all the albums and process the pictures with the blocks above
    [library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:assetGroupEnumerator failureBlock: failureBlock];


}//end viewDidLoad

Ответы [ 2 ]

21 голосов
/ 20 ноября 2011

Мне удалось получить исходное имя файла изображения следующим образом:

NSString* originalFileName = [[asset defaultRepresentation] filename];
0 голосов
/ 01 ноября 2011

Извлечение URL из ALAsset, выглядит следующим образом: assets-library: //asset/asset.JPG? Id = 1000000001 & ext = JPG

Если вам нужны разные имена файлов, создайте внутреннюю внешнюю парадигму:

#import <Foundation/Foundation.h>

@interface NSURL (NSURL_Asset)
- (NSURL*) toExternalForm;
- (NSURL*) fromExternalForm;
- (NSString*) toExternalFilename;    

@end

#import "NSURL+Asset.h"
#import "URLParser.h" // from http://iphone.demay-fr.net/2010/04/parsing-url-parameters-in-a-nsstring/

static NSString *const EXTERNAL_TOKEN = @"/assetExternalForm/";
@implementation NSURL (NSURL_Asset)

// assets-library://asset/asset.JPG/assetExternalForm/1000000001.JPG -> assets-library://asset/asset.JPG?id=1000000001&ext=JPG
- (NSURL*) fromExternalForm {
    if([self.scheme isEqualToString:@"assets-library"]) {
        NSRange slash = [self.absoluteString rangeOfString:EXTERNAL_TOKEN options:NSBackwardsSearch];
        if(slash.location != NSNotFound) {

            NSRange dot = [self.absoluteString rangeOfString:@"." options:NSBackwardsSearch];

            if(dot.location != NSNotFound) {
                NSString* extention = [self.absoluteString substringFromIndex:(dot.location + dot.length)];
                NSString* identifier = [self.absoluteString substringWithRange:NSMakeRange(slash.location + slash.length, dot.location - (slash.location + slash.length))];
                return [NSURL URLWithString:[NSString stringWithFormat:@"%@?id=%@&ext=%@", [self.absoluteString substringToIndex:slash.location], identifier, extention]];
            }
        }
    }
    return self;
}
// assets-library://asset/asset.JPG?id=1000000001&ext=JPG -> assets-library://asset/asset.JPG/assetExternalForm/1000000001.JPG
- (NSURL*) toExternalForm {
    if([self.scheme isEqualToString:@"assets-library"]) {
        NSRange range = [self.absoluteString rangeOfString:@"?"];
        if(range.location != NSNotFound) {
            URLParser *parser = [[[URLParser alloc] initWithURLString:self.absoluteString] autorelease];
            NSString* extention = [parser valueForVariable:@"ext"];
            NSString* identifier = [parser valueForVariable:@"id"];
            if(extention != NULL && identifier != NULL) {
                return [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@.%@", [self.absoluteString substringToIndex:range.location], EXTERNAL_TOKEN, identifier, extention]];
            }
        }
    }
    return self;
}
// assets-library://asset/asset.JPG?id=1000000001&ext=JPG -> 1000000001.JPG
- (NSString*) toExternalFilename {
    if([self.scheme isEqualToString:@"assets-library"]) {
        NSRange range = [self.absoluteString rangeOfString:@"?"];
        if(range.location != NSNotFound) {
            URLParser *parser = [[[URLParser alloc] initWithURLString:self.absoluteString] autorelease];
            NSString* extention = [parser valueForVariable:@"ext"];
            NSString* identifier = [parser valueForVariable:@"id"];

            if(extention != NULL && identifier != NULL) {
                return [NSString stringWithFormat:@"%@.%@", identifier, extention];
            }
        }
    }
    return NULL;
}
@end

Обратите внимание, что вам не нужно имя файла для чтения содержимого ALAsset.Для этого используйте метод ALAsset.defaultRepresentation.getBytes.

...