15

私はプロジェクトを開発しています。要件は次のとおりです。 - ユーザーはアプリケーションからカメラを開きます - 画像をキャプチャすると、キャプチャされた画像のメタデータにいくつかのデータが追加されます。私はいくつかのフォーラムを経験しました。このロジックをコーディングしてみました。私はその点に到達したと思いますが、画像に追加しているメタデータを見ることができないため、何かが欠けています. 私のコードは次のとおりです。

- (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

8 に答える 8

13

Apple は、この問題に対処する記事を更新しました (Technical Q&A QA1622)。古いバージョンの Xcode を使用している場合は、画像データの低レベルの解析なしではこれを行うことができないという記事がまだあるかもしれません。

https://developer.apple.com/library/ios/#qa/qa1622/_index.html

そこにあるコードを次のように調整しました。

- (void) saveImage:(UIImage *)imageToSave withInfo:(NSDictionary *)info
{
    // Get the assets library
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

    // Get the image metadata (EXIF & TIFF)
    NSMutableDictionary * imageMetadata = [[info objectForKey:UIImagePickerControllerMediaMetadata] mutableCopy];

    // add GPS data
    CLLocation * loc = <•••&gt;; // need a location here
    if ( loc ) {
        [imageMetadata setObject:[self gpsDictionaryForLocation:loc] forKey:(NSString*)kCGImagePropertyGPSDictionary];
    }

    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,imageMetadata);
        }
    };

    // Save the new image to the Camera Roll
    [library writeImageToSavedPhotosAlbum:[imageToSave CGImage] 
                                 metadata:imageMetadata 
                          completionBlock:imageWriteCompletionBlock];
    [imageMetadata release];
    [library release];
}

そして私はこれを

imagePickerController:didFinishPickingMediaWithInfo:

これは、イメージ ピッカーのデリゲート メソッドです。

ヘルパー メソッド ( GusUtilsから適応) を使用して、場所から GPS メタデータ ディクショナリを構築します。

- (NSDictionary *) gpsDictionaryForLocation:(CLLocation *)location
{
    CLLocationDegrees exifLatitude  = location.coordinate.latitude;
    CLLocationDegrees exifLongitude = location.coordinate.longitude;

    NSString * latRef;
    NSString * longRef;
    if (exifLatitude < 0.0) {
        exifLatitude = exifLatitude * -1.0f;
        latRef = @"S";
    } else {
        latRef = @"N";
    }

    if (exifLongitude < 0.0) {
        exifLongitude = exifLongitude * -1.0f;
        longRef = @"W";
    } else {
        longRef = @"E";
    }

    NSMutableDictionary *locDict = [[NSMutableDictionary alloc] init];

    [locDict setObject:location.timestamp forKey:(NSString*)kCGImagePropertyGPSTimeStamp];
    [locDict setObject:latRef forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
    [locDict setObject:[NSNumber numberWithFloat:exifLatitude] forKey:(NSString *)kCGImagePropertyGPSLatitude];
    [locDict setObject:longRef forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
    [locDict setObject:[NSNumber numberWithFloat:exifLongitude] forKey:(NSString *)kCGImagePropertyGPSLongitude];
    [locDict setObject:[NSNumber numberWithFloat:location.horizontalAccuracy] forKey:(NSString*)kCGImagePropertyGPSDOP];
    [locDict setObject:[NSNumber numberWithFloat:location.altitude] forKey:(NSString*)kCGImagePropertyGPSAltitude];

    return [locDict autorelease];

}

これまでのところ、これは iOS4 および iOS5 デバイスでうまく機能しています。

更新: および iOS6/iOS7 デバイス。このコードを使用して簡単なプロジェクトを作成しました。

https://github.com/5teev/MetaPhotoSave

于 2012-06-14T17:29:34.533 に答える
6

機能:UIImageWriteToSavePhotosAlbum 画像データのみを書き込みます。

ALAssetsLibraryを読む必要があります

最終的に呼び出したいメソッドは次のとおりです。

 ALAssetsLibrary *library = [[ALAssetsLibrary alloc]
 [library writeImageToSavedPhotosAlbum:metadata:completionBlock];
于 2011-11-01T13:36:57.110 に答える
2

アプリケーション内でカム キャプチャされた画像からメタ データを取得する:

UIImage *pTakenImage= [info objectForKey:@"UIImagePickerControllerOriginalImage"];

NSMutableDictionary *imageMetadata = [[NSMutableDictionary alloc] initWithDictionary:[info objectForKey:UIImagePickerControllerMediaMetadata]];

抽出されたメタデータを使用して画像をライブラリに保存します。

ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[sourceImage CGImage] metadata:imageMetadata completionBlock:Nil];
[library release];

またはローカルディレクトリに保存したい

CGImageDestinationAddImageFromSource(destinationPath,sourceImage,0, (CFDictionaryRef)imageMetadata);
于 2013-11-25T06:54:01.593 に答える
2

これには、GPS メタデータの生成が含まれます。これを行うための CLLocation のカテゴリを次に示します。

https://gist.github.com/phildow/6043486

于 2013-07-20T01:46:08.423 に答える