Can someone tell me how to read and edit the EXIF data on a photo in B4i?
Dim NaObj As NativeObject = Me
Dim EXIFMap As Map = NaObj.RunMethod("GetEXIF::",Array("PNG",LoadBitmap(File.DirAssets,"p2.png")))
For Each key In EXIFMap.Keys
Log(key & ": " & EXIFMap.Get(key))
Next
#If OBJC
#import <ImageIO/ImageIO.h>
-(B4IMap*) GetEXIF:(NSString *) Type :(UIImage *) Image{
NSDictionary* EXIFDic = nil;
NSData* ImageData;
if ([Type isEqualToString:@"JPEG"]){
ImageData = UIImageJPEGRepresentation(Image, 0.0);
}else if ([Type isEqualToString:@"PNG"]){
ImageData = UIImagePNGRepresentation(Image);
}
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)ImageData, NULL);
if (source){
CFDictionaryRef MetadataRef = CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
if (MetadataRef){
EXIFDic = [NSDictionary dictionaryWithDictionary : (__bridge NSDictionary *)MetadataRef];
CFRelease (MetadataRef);
}
CFRelease(source);
source = nil;
}
NSArray * Keys = [EXIFDic allKeys];
NSArray * Values = [EXIFDic allValues];
B4IMap * Map;
Map = [B4IMap new];
[Map Initialize];
int i;
for (i = 0; i < [Keys count]; i++){
[Map Put:(NSObject*)([Keys objectAtIndex:i]) :(NSObject*)([Values objectAtIndex:i])];
}
return Map;
}
#End If
{JFIF}: {
DensityUnit = 0;
JFIFVersion = (
1,
0,
1
);
XDensity = 72;
YDensity = 72;
}
Orientation: 1
PixelWidth: 1920
{TIFF}: {
Orientation = 1;
}
ColorModel: RGB
{Exif}: {
ColorSpace = 1;
PixelXDimension = 1920;
PixelYDimension = 1080;
}
Depth: 8
PixelHeight: 1080
GPS_LATITUDE, GPS_LONGITUDE, GPS_LATITUDE_REF, GPS_LONGITUDE_REFWhich Exif data do you want to set?
Dim NaObj As NativeObject = Me
'Save to PhotoAlbum
NaObj.RunMethod("SetGPS:Type:GPSLatitude:GPSLongitude:GPSLatitudeRef:GPSLongitudeRef:DataPath:WriteInPhotoAlbum:",Array(LoadBitmap(File.DirAssets,"x.jpg"),"JPEG",1.1,2.2,"lat_ref","lon_ref",Null,True))
'Save to Directory
NaObj.RunMethod("SetGPS:Type:GPSLatitude:GPSLongitude:GPSLatitudeRef:GPSLongitudeRef:DataPath:WriteInPhotoAlbum:",Array(LoadBitmap(File.DirAssets,"x.jpg"),"JPEG",1.1,2.2,"lat_ref","lon_ref",File.Combine(File.DirDocuments,"x.jpeg"),False))
End Sub
#If OBJC
#import <ImageIO/ImageIO.h>
#import <AssetsLibrary/AssetsLibrary.h>
- (void)SetGPS:(UIImage *)Image Type:(NSString*)Type GPSLatitude:(float)GPSLatitude GPSLongitude:(float)GPSLongitude GPSLatitudeRef:(NSString*)GPSLatitudeRef GPSLongitudeRef:(NSString*)GPSLongitudeRef DataPath:(NSString*)DataPath WriteInPhotoAlbum:(BOOL)WriteInPhotoAlbum {
NSData* ImageData;
if ([Type isEqualToString:@"JPEG"]){
ImageData = UIImageJPEGRepresentation(Image, 1.0);
}else if ([Type isEqualToString:@"PNG"]){
ImageData = UIImagePNGRepresentation(Image);
}
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)ImageData, NULL);
NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
NSMutableDictionary *metadataAsMutable = [metadata mutableCopy];
NSMutableDictionary *GPSDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy];
if(!GPSDictionary)
{
NSDictionary * dictionary = nil;
GPSDictionary = [NSMutableDictionary dictionary];
}
[GPSDictionary setValue:[NSNumber numberWithFloat:GPSLatitude] forKey:(NSString*)kCGImagePropertyGPSLatitude];
[GPSDictionary setValue:[NSNumber numberWithFloat:GPSLongitude] forKey:(NSString*)kCGImagePropertyGPSLongitude];
[GPSDictionary setValue:GPSLatitudeRef forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
[GPSDictionary setValue:GPSLongitudeRef forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
[metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];
if (WriteInPhotoAlbum == YES){
ALAssetsLibrary *library = [ALAssetsLibrary alloc];
ALAssetsLibraryWriteImageCompletionBlock imageWriteCompletionBlock =
^(NSURL *newURL, NSError *error) {
if (error) {
NSLog( @"Error writing image with metadata to Photo Library: %@", error );
} else {
NSLog( @"Wrote image %@ with metadata %@ to Photo Library",newURL,metadataAsMutable);
}
};
[library writeImageToSavedPhotosAlbum:Image.CGImage
metadata:metadataAsMutable
completionBlock:imageWriteCompletionBlock];
}else{
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----------");
}else{
[dest_data writeToFile:DataPath atomically:YES];
NSLog( @"Wrote image to %@ with metadata %@",DataPath,metadataAsMutable);
}
}
}
#End If
'Orientations:
'Up = 0
'Down = 1
'Left = 2
'Right = 3
'UpMirrored = 4
'DownMirrored = 5
'LeftMirrored = 6
'RightMirrored = 7
Sub SetOrientation(b As Bitmap, O As Int) As Bitmap
Dim NaObj2 As NativeObject = b
Dim NaObj As NativeObject
Return NaObj.Initialize("UIImage").RunMethod("imageWithCGImage:scale:orientation:",Array(NaObj2.RunMethod("CGImage",Null),NaObj2.RunMethod("scale",Null),o))
End Sub
I have never written that I can't do itWhy cant you create a complete library like jpeg library for android..
Dim theMetaMap As Map=getImageMetaData(filename)
Dim theExifMap As Map=theMetaMap.get("{Exif}")
public Sub getImageMetaData(filename As String) As Map
Dim nome As NativeObject=Me
Dim imageMetaData As Object = nome.RunMethod("getImageMetaData:",Array(filename))
Return NSDictionaryToMap(imageMetaData)
End Sub
Sub NSDictionaryToMap(Dictionary As Object) As Map
Dim NewMap As NativeObject
NewMap = NewMap.Initialize("B4IMap").RunMethod("convertToMap:",Array(Dictionary))
Return NewMap
End Sub
#if OBJC
#import <ImageIO/ImageIO.h>
- (NSDictionary*) getImageMetaData : (NSString*) file
{
NSDictionary* dic = nil;
NSURL *imageFileURL = [NSURL fileURLWithPath: file];
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, nil);
if (imageSource == nil) {
return nil;
}
CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil);
CFRelease(imageSource);
if (imageProperties != nil) {
if ( imageProperties )
{
NSDictionary* immutableImageProerties = (__bridge NSDictionary *)imageProperties;
if ( immutableImageProerties )
{
dic =
[ NSDictionary dictionaryWithDictionary : (__bridge NSDictionary *)imageProperties ];
}
CFRelease (imageProperties);
}
}
return dic;
}
#End If
Hi, based on http://stackoverflow.com/questions/...tadata-exif-gps-tiff-in-iphones-photo-library:
B4X:Dim NaObj As NativeObject = Me 'Save to PhotoAlbum NaObj.RunMethod("SetGPS:Type:GPSLatitude:GPSLongitude:GPSLatitudeRef:GPSLongitudeRef:DataPath:WriteInPhotoAlbum:",Array(LoadBitmap(File.DirAssets,"x.jpg"),"JPEG",1.1,2.2,"lat_ref","lon_ref",Null,True)) 'Save to Directory NaObj.RunMethod("SetGPS:Type:GPSLatitude:GPSLongitude:GPSLatitudeRef:GPSLongitudeRef:DataPath:WriteInPhotoAlbum:",Array(LoadBitmap(File.DirAssets,"x.jpg"),"JPEG",1.1,2.2,"lat_ref","lon_ref",File.Combine(File.DirDocuments,"x.jpeg"),False)) End Sub #If OBJC #import <ImageIO/ImageIO.h> #import <AssetsLibrary/AssetsLibrary.h> - (void)SetGPS:(UIImage *)Image Type:(NSString*)Type GPSLatitude:(float)GPSLatitude GPSLongitude:(float)GPSLongitude GPSLatitudeRef:(NSString*)GPSLatitudeRef GPSLongitudeRef:(NSString*)GPSLongitudeRef DataPath:(NSString*)DataPath WriteInPhotoAlbum:(BOOL)WriteInPhotoAlbum { NSData* ImageData; if ([Type isEqualToString:@"JPEG"]){ ImageData = UIImageJPEGRepresentation(Image, 1.0); }else if ([Type isEqualToString:@"PNG"]){ ImageData = UIImagePNGRepresentation(Image); } CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)ImageData, NULL); NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL); NSMutableDictionary *metadataAsMutable = [metadata mutableCopy]; NSMutableDictionary *GPSDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy]; if(!GPSDictionary) { NSDictionary * dictionary = nil; GPSDictionary = [NSMutableDictionary dictionary]; } [GPSDictionary setValue:[NSNumber numberWithFloat:GPSLatitude] forKey:(NSString*)kCGImagePropertyGPSLatitude]; [GPSDictionary setValue:[NSNumber numberWithFloat:GPSLongitude] forKey:(NSString*)kCGImagePropertyGPSLongitude]; [GPSDictionary setValue:GPSLatitudeRef forKey:(NSString*)kCGImagePropertyGPSLatitudeRef]; [GPSDictionary setValue:GPSLongitudeRef forKey:(NSString*)kCGImagePropertyGPSLongitudeRef]; [metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary]; if (WriteInPhotoAlbum == YES){ ALAssetsLibrary *library = [ALAssetsLibrary alloc]; ALAssetsLibraryWriteImageCompletionBlock imageWriteCompletionBlock = ^(NSURL *newURL, NSError *error) { if (error) { NSLog( @"Error writing image with metadata to Photo Library: %@", error ); } else { NSLog( @"Wrote image %@ with metadata %@ to Photo Library",newURL,metadataAsMutable); } }; [library writeImageToSavedPhotosAlbum:Image.CGImage metadata:metadataAsMutable completionBlock:imageWriteCompletionBlock]; }else{ 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----------"); }else{ [dest_data writeToFile:DataPath atomically:YES]; NSLog( @"Wrote image to %@ with metadata %@",DataPath,metadataAsMutable); } } } #End If
I have not tested yet.It should work ....