1.ALAssetRepresentation* representation = [[self assetAtIndex:index] 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];
if (length==0) return 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);
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);
——————————————————————————————————————————————-
2.
The API has changed the rules slightly and you dont get direct file system access to the iPhoto library any more. Instead you get asset library URL’s like this.
assets-library://asset/asset.JPG?id=1000000003&ext=JPG
You use the ALAssetLibrary object to access the ALAsset object via the URL.
so from the docs for ALAssetLibrary throw this in a header (or your source)
typedefvoid(^ALAssetsLibraryAssetForURLResultBlock)(ALAsset*asset);
typedefvoid(^ALAssetsLibraryAccessFailureBlock)(NSError*error);
which isnt strictly needed but keeps things pretty.
and then in your source.
-(void)findLargeImage
{
NSString*mediaurl =[self.node valueForKey:kVMMediaURL];
//
ALAssetsLibraryAssetForURLResultBlock resultblock =^(ALAsset*myasset)
{
ALAssetRepresentation*rep =[myasset defaultRepresentation];
CGImageRef iref =[rep fullResolutionImage];
if(iref){
largeimage =[UIImage imageWithCGImage:iref];
[largeimage retain];
}
};
//
ALAssetsLibraryAccessFailureBlock failureblock =^(NSError*myerror)
{
NSLog(@”booya, cant get image – %@”,[myerror localizedDescription]);
};
if(mediaurl &&[mediaurl length]&&![[mediaurl pathExtension] isEqualToString:AUDIO_EXTENSION])
{
[largeimage release];
NSURL *asseturl =[NSURL URLWithString:mediaurl];
ALAssetsLibrary* assetslibrary =[[[ALAssetsLibrary alloc] init] autorelease];
[assetslibrary assetForURL:asseturl
resultBlock:resultblock
failureBlock:failureblock];
}
}
A couple of things to note are that this uses blocks which were new to me before I started my iOS4 porting but you might like to look at
http://www.mikeash.com/pyblog/friday-qa-2008-12-26.html
and
They bend your head a little but if you think of them as notification selectors or callbacks it kind of helps.
Also
- when findLargeImage returns theresultblock wont have run yet as itsa callback. So largeImage wont bevalid yet.
- largeImage needs to be aninstance variable not scoped to themethod.
I use this construct to do this when using the method but you may find something more suitable to your use.
[node.view findLargeImage];
UIImage*thumb = node.view.largeImage;
if(thumb){ blah blah }
Thats what I learned while trying to get this working anyway.
iOS 5 update
When the result block fires seems to be a bit slower with iOS5 & maybe single core devices so I couldnt rely on the image to be available directly after calling findLargeImage. So I changed it to call out to a delegate.
@protocolHiresImageDelegate<NSObject>
@optional
-(void)hiresImageAvailable:(UIImage*)aimage;
@end
and comme cá
//
ALAssetsLibraryAssetForURLResultBlock resultblock =^(ALAsset*myasset)
{
ALAssetRepresentation*rep =[myasset defaultRepresentation];
CGImageRef iref =[rep fullResolutionImage];
if(iref){
UIImage*largeimage =[UIImage imageWithCGImage:iref];
[delegate hiresImageAvailable:large];
}
};
——————————————————————————————————————————————————–
3.
I am developing one project. The requirements are like that, User will open the cam thru application and on the capture of Image, some data will be appended to the captured image’s metadata. I have gone thru some of the forums. I tried to code this logic. I guess, I have reached to the point, but something is missing as I am not able to see the metadata that I am appending to the image. My code as follows,
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)dictionary
{
[picker dismissModalViewControllerAnimated:YES];
NSData*dataOfImageFromGallery =UIImageJPEGRepresentation(image,0.5);
NSLog(@”Image length: %d”,[dataOfImageFromGallery length]);
CGImageSourceRef source;
source =CGImageSourceCreateWithData((CFDataRef)dataOfImageFromGallery, NULL);
NSDictionary*metadata =(NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source,0, NULL);
NSMutableDictionary*metadataAsMutable =[[metadata mutableCopy]autorelease];
[metadata release];
NSMutableDictionary*EXIFDictionary=[[[metadataAsMutable objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy]autorelease];
NSMutableDictionary*GPSDictionary=[[[metadataAsMutable objectForKey:(NSString*)kCGImagePropertyGPSDictionary]mutableCopy]autorelease];
if(!EXIFDictionary)
{
//if the image does not have an EXIF dictionary (not all images do), then create one for us to use
EXIFDictionary=[NSMutableDictionary dictionary];
}
if(!GPSDictionary)
{
GPSDictionary=[NSMutableDictionary dictionary];
}
//Setup GPS dict –
//I am appending my custom data just to test the logic……..
[GPSDictionary setValue:[NSNumber numberWithFloat:1.1] forKey:(NSString*)kCGImagePropertyGPSLatitude];
[GPSDictionary setValue:[NSNumber numberWithFloat:2.2] forKey:(NSString*)kCGImagePropertyGPSLongitude];
[GPSDictionary setValue:@”lat_ref” forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
[GPSDictionary setValue:@”lon_ref” forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
[GPSDictionary setValue:[NSNumber numberWithFloat:3.3] forKey:(NSString*)kCGImagePropertyGPSAltitude];
[GPSDictionary setValue:[NSNumber numberWithShort:4.4] forKey:(NSString*)kCGImagePropertyGPSAltitudeRef];
[GPSDictionary setValue:[NSNumber numberWithFloat:5.5] forKey:(NSString*)kCGImagePropertyGPSImgDirection];
[GPSDictionary setValue:@”_headingRef” forKey:(NSString*)kCGImagePropertyGPSImgDirectionRef];
[EXIFDictionary setValue:@”xml_user_comment” forKey:(NSString*)kCGImagePropertyExifUserComment];
//add our modified EXIF data back into the image’s metadata
[metadataAsMutable setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary];
[metadataAsMutable setObject:GPSDictionary forKey:(NSString*)kCGImagePropertyGPSDictionary];
CFStringRef UTI =CGImageSourceGetType(source);
NSMutableData*dest_data =[NSMutableData data];
CGImageDestinationRef destination =CGImageDestinationCreateWithData((CFMutableDataRef) dest_data, UTI,1, NULL);
if(!destination)
{
NSLog(@”——— Could not create image destination———“);
}
CGImageDestinationAddImageFromSource(destination, source,0,(CFDictionaryRef) metadataAsMutable);
BOOL success = NO;
success =CGImageDestinationFinalize(destination);
if(!success)
{
NSLog(@”——– could not create data from image destination———-“);
}
UIImage* image1 =[[UIImage alloc] initWithData:dest_data];
UIImageWriteToSavedPhotosAlbum(image1, self, nil, nil);
}
————————————————————————————————————————–
4.
#import <ImageIO/CGImageSource.h>
#import <ImageIO/CGImageProperties.h>
NSString* imagePath = resource.file.filePath;
NSURL* url = [NSURL fileURLWithPath:imagePath];
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
NSDictionary* metadata = (NSDictionary *)(NSString*)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
NSDictionary* exifData = [metadata valueForKey:(NSString*)kCGImagePropertyExifDictionary];
NSString* dateString = [[exifData valueForKey:(NSString*)kCGImagePropertyExifDateTimeDigitized] value];
NSLog(dateString);
[metadata release];
CFRelease(source);