objective-c - una - pasar fotos de iphone a pc windows 10
¿Cómo obtener el nombre de archivo original de una foto en iOS? (2)
Actualmente estoy desarrollando una aplicación para iPad en la que un usuario ingresará un nombre de archivo de foto en un campo de texto (como parte de notas de campo), luego importarán sus fotos a la biblioteca de fotos del iPad. La aplicación accederá a la biblioteca usando ALAssetsLibrary y enumerará las fotos, buscando las que tengan el nombre de archivo que ingresaron en sus notas de campo. Este sería el nombre de archivo dado a la foto por la cámara que lo tomó. Por ejemplo "DSC_0019.JPG".
¿No es esto posible?
Noté que si importo fotos de mi cámara al iPad, luego abro iPhoto en mi Mac y miro el iPad como una cámara, puedo "obtener información" sobre las imágenes que se guardan en el iPad y ver el nombre del archivo original que estoy buscando para. Sin embargo, esto no está incluido en los metadatos del iPad.
Cualquier ayuda sería muy apreciada.
Aquí está mi código:
(Al trabajar con CFDictionary, casi todo es nulo excepto las teclas Exif que no tienen lo que estoy buscando)
- (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
Extraiga la URL del ALAsset, se ve así: assets-library: //asset/asset.JPG? Id = 1000000001 & ext = JPG
Si necesita diferentes nombres de archivo, cree un paradigma interno-externo:
#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
Tenga en cuenta que no necesita un nombre de archivo para leer el contenido de un ALAsset. Utilice el método ALAsset.defaultRepresentation.getBytes para eso.
Pude obtener el nombre de archivo original de una imagen así:
NSString* originalFileName = [[asset defaultRepresentation] filename];