exif ios
2016-04-11 15:52:31 wuzuyu365 阅读数 2257


#include "AssetsLibrary/ALAssetsLibrary.h"
#include "AssetsLibrary/ALAssetRepresentation.h"
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)   {
        ALAssetRepresentation *representation = [myasset defaultRepresentation];
        NSLog(@"meta=%@",[representation metadata]);
        
        NSString *fileName = [representation filename];
        NSLog(@"fileName : %@",fileName);
    };
    
    ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init]  ;
    [assetslibrary assetForURL:imageURL
                   resultBlock:resultblock
                  failureBlock:nil];
}

meta={

    ColorModel = RGB;

    DPIHeight = 72;

    DPIWidth = 72;

    Depth = 8;

    Orientation = 6;

    PixelHeight = 2448;

    PixelWidth = 3264;

    ProfileName = "sRGB IEC61966-2.1";

    "{ExifAux}" =     {

        Regions =         {

            HeightAppliedTo = 2448;

            RegionList =             (

                                {

                    AngleInfoRoll = 270;

                    AngleInfoYaw = 0;

                    ConfidenceLevel = 261;

                    FaceID = 12;

                    Height = "0.074755";

                    Timestamp = 2147483647;

                    Type = Face;

                    Width = "0.056066";

                    X = "0.399663";

                    Y = "0.587214";

                }

            );

            WidthAppliedTo = 3264;

        };

    };

    "{Exif}" =     {

        ApertureValue = "2.275007206687806";

        BrightnessValue = "10.71860465116279";

        ColorSpace = 1;

        ComponentsConfiguration =         (

            1,

            2,

            3,

            0

        );

        DateTimeDigitized = "2015:06:05 09:55:26";

        DateTimeOriginal = "2015:06:05 09:55:26";

        ExifVersion =         (

            2,

            2,

            1

        );

        ExposureBiasValue = 0;

        ExposureMode = 0;

        ExposureProgram = 2;

        ExposureTime = "0.0003409478349812479";

        FNumber = "2.2";

        Flash = 16;

        FlashPixVersion =         (

            1,

            0

        );

        FocalLenIn35mmFilm = 29;

        FocalLength = "4.15";

        ISOSpeedRatings =         (

            32

        );

        LensMake = Apple;

        LensModel = "iPhone 5s back camera 4.15mm f/2.2";

        LensSpecification =         (

            "4.15",

            "4.15",

            "2.2",

            "2.2"

        );

        MeteringMode = 5;

        PixelXDimension = 3264;

        PixelYDimension = 2448;

        SceneCaptureType = 0;

        SceneType = 1;

        SensingMethod = 2;

        ShutterSpeedValue = "11.5179407176287";

        SubjectArea =         (

            1301,

            1433,

            182,

            181

        );

        SubsecTimeDigitized = 905;

        SubsecTimeOriginal = 905;

        WhiteBalance = 0;

    };

    "{GPS}" =     {

        Altitude = "9.596343178621659";

        AltitudeRef = 0;

        DateStamp = "2015:06:05";

        DestBearing = "217.6901408450704";

        DestBearingRef = M;

        ImgDirection = "37.69015544041451";

        ImgDirectionRef = M;

        Latitude = "22.36720333333333";

        LatitudeRef = N;

        Longitude = "113.54242";

        LongitudeRef = E;

        Speed = 0;

        SpeedRef = K;

        TimeStamp = "01:55:26";

    };

    "{MakerApple}" =     {

        1 = 2;

        14 = 1;

        2 = <f801d201 d801a801 1801b800 5d006e00 81006400 63006900 66006300 49005d00 e201dc01 2102ac01 b2007100 5a007d00 84006300 5f006b00 6a005b00 3e005300 d201f501 1f027e01 a4006600 7100a800 78006600 5f006b00 68005800 3f004e00 e9011502 f301a301 97006400 5000a900 7a006400 5d006a00 6b005500 3c005100 0f020d02 fb014c01 95005400 5200e400 c3009100 5d006700 6a005300 38004d00 1502cc01 af012701 1f016800 a2002e02 4301ac00 7d003100 41003f00 2d003700 cd01a401 af012101 b4007600 ec008601 ed00bf00 fd001f00 13002300 1d002400 6f019701 ad012201 a3006300 de00fa02 df01e700 2a001200 0f001000 12002300 4001a501 80012701 9b006100 8700d301 9e01e600 32002b00 4b005200 3b003100 2b016a01 53012c01 8a00ad00 89003002 67029901 3f000a00 12000c00 13003000 2f014b01 56011e01 84005500 ed001403 42022e02 49000c00 14002100 22002600 52019d01 49010901 76005200 7300c001 cb01e700 78003b00 48003d00 3c003f00 8e01a301 2b01ff00 62003600 72008200 7f006b00 61005500 5a005600 51005200 ac017c01 ff001501 6e003900 61008100 76006700 5c005100 55005a00 52004d00 db015f01 f9003401 c4004700 75008100 77006500 57005000 56005600 4f004c00 d6014f01 57014601 8b003e00 92008000 77006000 57005200 4f005700 52004b00>;

        3 =         {

            epoch = 0;

            flags = 1;

            timescale = 1000000000;

            value = 801371064569041;

        };

        4 = 1;

        5 = 186;

        6 = 180;

        7 = 1;

        8 =         (

            "-0.02023194",

            "-0.9834778",

            "-0.1565095"

        );

    };

    "{TIFF}" =     {

        DateTime = "2015:06:05 09:55:26";

        Make = Apple;

        Model = "iPhone 5s";

        Orientation = 6;

        ResolutionUnit = 2;

        Software = "8.3";

        XResolution = 72;

        YResolution = 72;

    };

}


2017-08-03 12:00:09 yidu_blog 阅读数 1255



[objc] view plain copy
  1. #include "AssetsLibrary/ALAssetsLibrary.h"  
  2. #include "AssetsLibrary/ALAssetRepresentation.h"  
[objc] view plain copy
  1. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {  
  2.     NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];  
  3.     ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)   {  
  4.         ALAssetRepresentation *representation = [myasset defaultRepresentation];  
  5.         NSLog(@"meta=%@",[representation metadata]);  
  6.           
  7.         NSString *fileName = [representation filename];  
  8.         NSLog(@"fileName : %@",fileName);  
  9.     };  
  10.       
  11.     ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init]  ;  
  12.     [assetslibrary assetForURL:imageURL  
  13.                    resultBlock:resultblock  
  14.                   failureBlock:nil];  
  15. }  

meta={

    ColorModel = RGB;

    DPIHeight = 72;

    DPIWidth = 72;

    Depth = 8;

    Orientation = 6;

    PixelHeight = 2448;

    PixelWidth = 3264;

    ProfileName = "sRGB IEC61966-2.1";

    "{ExifAux}" =     {

        Regions =         {

            HeightAppliedTo = 2448;

            RegionList =             (

                                {

                    AngleInfoRoll = 270;

                    AngleInfoYaw = 0;

                    ConfidenceLevel = 261;

                    FaceID = 12;

                    Height = "0.074755";

                    Timestamp = 2147483647;

                    Type = Face;

                    Width = "0.056066";

                    X = "0.399663";

                    Y = "0.587214";

                }

            );

            WidthAppliedTo = 3264;

        };

    };

    "{Exif}" =     {

        ApertureValue = "2.275007206687806";

        BrightnessValue = "10.71860465116279";

        ColorSpace = 1;

        ComponentsConfiguration =         (

            1,

            2,

            3,

            0

        );

        DateTimeDigitized = "2015:06:05 09:55:26";

        DateTimeOriginal = "2015:06:05 09:55:26";

        ExifVersion =         (

            2,

            2,

            1

        );

        ExposureBiasValue = 0;

        ExposureMode = 0;

        ExposureProgram = 2;

        ExposureTime = "0.0003409478349812479";

        FNumber = "2.2";

        Flash = 16;

        FlashPixVersion =         (

            1,

            0

        );

        FocalLenIn35mmFilm = 29;

        FocalLength = "4.15";

        ISOSpeedRatings =         (

            32

        );

        LensMake = Apple;

        LensModel = "iPhone 5s back camera 4.15mm f/2.2";

        LensSpecification =         (

            "4.15",

            "4.15",

            "2.2",

            "2.2"

        );

        MeteringMode = 5;

        PixelXDimension = 3264;

        PixelYDimension = 2448;

        SceneCaptureType = 0;

        SceneType = 1;

        SensingMethod = 2;

        ShutterSpeedValue = "11.5179407176287";

        SubjectArea =         (

            1301,

            1433,

            182,

            181

        );

        SubsecTimeDigitized = 905;

        SubsecTimeOriginal = 905;

        WhiteBalance = 0;

    };

    "{GPS}" =     {

        Altitude = "9.596343178621659";

        AltitudeRef = 0;

        DateStamp = "2015:06:05";

        DestBearing = "217.6901408450704";

        DestBearingRef = M;

        ImgDirection = "37.69015544041451";

        ImgDirectionRef = M;

        Latitude = "22.36720333333333";

        LatitudeRef = N;

        Longitude = "113.54242";

        LongitudeRef = E;

        Speed = 0;

        SpeedRef = K;

        TimeStamp = "01:55:26";

    };

    "{MakerApple}" =     {

        1 = 2;

        14 = 1;

        2 = <f801d201 d801a801 1801b800 5d006e00 81006400 63006900 66006300 49005d00 e201dc01 2102ac01 b2007100 5a007d00 84006300 5f006b00 6a005b00 3e005300 d201f501 1f027e01 a4006600 7100a800 78006600 5f006b00 68005800 3f004e00 e9011502 f301a301 97006400 5000a900 7a006400 5d006a00 6b005500 3c005100 0f020d02 fb014c01 95005400 5200e400 c3009100 5d006700 6a005300 38004d00 1502cc01 af012701 1f016800 a2002e02 4301ac00 7d003100 41003f00 2d003700 cd01a401 af012101 b4007600 ec008601 ed00bf00 fd001f00 13002300 1d002400 6f019701 ad012201 a3006300 de00fa02 df01e700 2a001200 0f001000 12002300 4001a501 80012701 9b006100 8700d301 9e01e600 32002b00 4b005200 3b003100 2b016a01 53012c01 8a00ad00 89003002 67029901 3f000a00 12000c00 13003000 2f014b01 56011e01 84005500 ed001403 42022e02 49000c00 14002100 22002600 52019d01 49010901 76005200 7300c001 cb01e700 78003b00 48003d00 3c003f00 8e01a301 2b01ff00 62003600 72008200 7f006b00 61005500 5a005600 51005200 ac017c01 ff001501 6e003900 61008100 76006700 5c005100 55005a00 52004d00 db015f01 f9003401 c4004700 75008100 77006500 57005000 56005600 4f004c00 d6014f01 57014601 8b003e00 92008000 77006000 57005200 4f005700 52004b00>;

        3 =         {

            epoch = 0;

            flags = 1;

            timescale = 1000000000;

            value = 801371064569041;

        };

        4 = 1;

        5 = 186;

        6 = 180;

        7 = 1;

        8 =         (

            "-0.02023194",

            "-0.9834778",

            "-0.1565095"

        );

    };

    "{TIFF}" =     {

        DateTime = "2015:06:05 09:55:26";

        Make = Apple;

        Model = "iPhone 5s";

        Orientation = 6;

        ResolutionUnit = 2;

        Software = "8.3";

        XResolution = 72;

        YResolution = 72;

    };

}


2015-04-29 16:10:14 u012681458 阅读数 2501

http://www.itstrike.cn/Question/d273055c-0644-4568-b0af-414af69e3f39.html


无数的尝试和每一等答案 + 谷歌通过筛分结果之后,它很困惑我那在 iOS 上处理 EXIF 是如此令人沮丧。

下面是工作的代码,它的结果。

[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
    completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
    {
        NSData *imageNSData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

        CGImageSourceRef imgSource = CGImageSourceCreateWithData((__bridge_retained CFDataRef)imageNSData, NULL);

        //get all the metadata in the image
        NSDictionary *metadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imgSource, 0, NULL);

        NSLog(@"original metadata Info: %@",metadata);

        //make the metadata dictionary mutable so we can add properties to it
        NSMutableDictionary *metadataAsMutable = [metadata mutableCopy];

        NSMutableDictionary *EXIFDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy];
        NSMutableDictionary *GPSDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy];
        NSMutableDictionary *RAWDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyRawDictionary]mutableCopy];

        if(!EXIFDictionary)
            EXIFDictionary = [[NSMutableDictionary dictionary] init];

        if(!GPSDictionary)
            GPSDictionary = [[NSMutableDictionary dictionary] init];

        if(!RAWDictionary)
            RAWDictionary = [[NSMutableDictionary dictionary] init];


        [GPSDictionary setObject:@"camera coord Latitude"
                         forKey:(NSString*)kCGImagePropertyGPSLatitude];
        [GPSDictionary setObject:@"camera coord Longitude"
                         forKey:(NSString*)kCGImagePropertyGPSLongitude];
        [GPSDictionary setObject:@"camera GPS Date Stamp"
                         forKey:(NSString*)kCGImagePropertyGPSDateStamp];
        [GPSDictionary setObject:@"camera direction (heading) in degrees"
                         forKey:(NSString*)kCGImagePropertyGPSImgDirection];

        [GPSDictionary setObject:@"subject coord Latitude"
                         forKey:(NSString*)kCGImagePropertyGPSDestLatitude];
        [GPSDictionary setObject:@"subject coord Longitude"
                         forKey:(NSString*)kCGImagePropertyGPSDestLongitude];

        [EXIFDictionary setObject:@"[S.D.] kCGImagePropertyExifUserComment"
                           forKey:(NSString *)kCGImagePropertyExifUserComment];

        [EXIFDictionary setValue:@"69 m" forKey:(NSString *)kCGImagePropertyExifSubjectDistance];


        //Add the modified Data back into the image’s metadata
        [metadataAsMutable setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyExifDictionary];
        [metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];
        [metadataAsMutable setObject:RAWDictionary forKey:(NSString *)kCGImagePropertyRawDictionary];


        NSLog(@"metadataAsMutable Info: %@",metadataAsMutable);

        CFStringRef UTI = CGImageSourceGetType(imgSource); //this is the type of image (e.g., public.jpeg)

        //this will be the data CGImageDestinationRef will write into
        NSMutableData *newImageData = [NSMutableData data];

        CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)newImageData, UTI, 1, NULL);

        if(!destination)
            NSLog(@"***Could not create image destination ***");

        //add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
        CGImageDestinationAddImageFromSource(destination, imgSource, 0, (__bridge CFDictionaryRef) metadataAsMutable);

        //tell the destination to write the image data and metadata into our data object.
        //It will return false if something goes wrong
        BOOL success = NO;
        success = CGImageDestinationFinalize(destination);

        if(!success)
            NSLog(@"***Could not create data from image destination ***");

        CIImage *testImage = [CIImage imageWithData:newImageData];
        NSDictionary *propDict = [testImage properties];
        NSLog(@"Properties %@", propDict);

    }];

其中输出这:

2012-10-12 23:17:45.415 Waypointer[3120:907] original metadata Info: {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
Depth = 8;
Orientation = 1;
PixelHeight = 2448;
PixelWidth = 3264;
"{Exif}" =     {
    ApertureValue = "2.526069";
    BrightnessValue = "-4.410617";
    ColorSpace = 1;
    ComponentsConfiguration =         (
        1,
        2,
        3,
        0
    );
    ExifVersion =         (
        2,
        2,
        1
    );
    ExposureMode = 0;
    ExposureProgram = 2;
    ExposureTime = "0.06666667";
    FNumber = "2.4";
    Flash = 16;
    FlashPixVersion =         (
        1,
        0
    );
    FocalLenIn35mmFilm = 35;
    FocalLength = "4.28";
    ISOSpeedRatings =         (
        800
    );
    MeteringMode = 5;
    PixelXDimension = 3264;
    PixelYDimension = 2448;
    SceneCaptureType = 0;
    SensingMethod = 2;
    ShutterSpeedValue = "3.906905";
    SubjectArea =         (
        1631,
        1223,
        881,
        881
    );
    WhiteBalance = 0;
};
"{TIFF}" =     {
    Orientation = 1;
    ResolutionUnit = 2;
    XResolution = 72;
    YResolution = 72;
    "_YCbCrPositioning" = 1;
};
}

和这:

2012-10-12 23:17:45.421 Waypointer[3120:907] metadataAsMutable Info: {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
Depth = 8;
Orientation = 1;
PixelHeight = 2448;
PixelWidth = 3264;
"{Exif}" =     {
    ApertureValue = "2.526069";
    BrightnessValue = "-4.410617";
    ColorSpace = 1;
    ComponentsConfiguration =         (
        1,
        2,
        3,
        0
    );
    ExifVersion =         (
        2,
        2,
        1
    );
    ExposureMode = 0;
    ExposureProgram = 2;
    ExposureTime = "0.06666667";
    FNumber = "2.4";
    Flash = 16;
    FlashPixVersion =         (
        1,
        0
    );
    FocalLenIn35mmFilm = 35;
    FocalLength = "4.28";
    ISOSpeedRatings =         (
        800
    );
    MeteringMode = 5;
    PixelXDimension = 3264;
    PixelYDimension = 2448;
    SceneCaptureType = 0;
    SensingMethod = 2;
    ShutterSpeedValue = "3.906905";
    SubjectArea =         (
        1631,
        1223,
        881,
        881
    );
    SubjectDistance = "69 m";
    UserComment = "[S.D.] kCGImagePropertyExifUserComment";
    WhiteBalance = 0;
};
"{GPS}" =     {
    DateStamp = "camera GPS Date Stamp";
    DestLatitude = "subject coord Latitude";
    DestLongitude = "subject coord Longitude";
    ImgDirection = "camera direction (heading) in degrees";
    Latitude = "camera coord Latitude";
    Longitude = "camera coord Longitude";
};
"{Raw}" =     {
};
"{TIFF}" =     {
    Orientation = 1;
    ResolutionUnit = 2;
    XResolution = 72;
    YResolution = 72;
    "_YCbCrPositioning" = 1;
};
}

并且,在它以后所有,这样做:

2012-10-12 23:17:47.131 Waypointer[3120:907] Properties {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
Depth = 8;
Orientation = 1;
PixelHeight = 2448;
PixelWidth = 3264;
"{Exif}" =     {
    ApertureValue = "2.526069";
    BrightnessValue = "-4.410617";
    ColorSpace = 1;
    ComponentsConfiguration =         (
        0,
        0,
        0,
        1
    );
    ExifVersion =         (
        2,
        2,
        1
    );
    ExposureMode = 0;
    ExposureProgram = 2;
    ExposureTime = "0.06666667";
    FNumber = "2.4";
    Flash = 16;
    FlashPixVersion =         (
        1,
        0
    );
    FocalLenIn35mmFilm = 35;
    FocalLength = "4.28";
    ISOSpeedRatings =         (
        800
    );
    MeteringMode = 5;
    PixelXDimension = 3264;
    PixelYDimension = 2448;
    SceneCaptureType = 0;
    SensingMethod = 2;
    ShutterSpeedValue = "3.906905";
    SubjectArea =         (
        1631,
        1223,
        881,
        881
    );
    UserComment = "[S.D.] kCGImagePropertyExifUserComment";
    WhiteBalance = 0;
};
"{JFIF}" =     {
    DensityUnit = 1;
    JFIFVersion =         (
        1,
        1
    );
    XDensity = 72;
    YDensity = 72;
};
"{TIFF}" =     {
    Orientation = 1;
    ResolutionUnit = 2;
    XResolution = 72;
    YResolution = 72;
    "_YCbCrPositioning" = 1;
};
}

如示例所示,您可以看到该图像的原始元数据、 其修改,然后其最终的输出。

最终的输出正是困扰我的因为不管我做什么,无法坚持我修改后的值!

有一些非常具体的格式我错过吗?为什么 iOS 剥离所做的修改?我是否需要做来添加这些额外的值?他们是在.header 中列出,并且觉得它应该很容易接受。

解决方法 1:

斯科特,在苹果公司,开发人员与我事件报告返回和固定的问题:

前面的代码上面写入字符串值的 GPS 值-这不会工作,他们必须为 NS/CFNumbers (我们提取 EXIF 一个浮点值)。

我将会申请一个 bug 报告给苹果反对它们的文档。

虽然花了一个星期才能拿这种反应,我真的很欣赏苹果向开发者提供的支持。(感谢斯科特!);-)

下面是改进了代码和其正确的输出:

[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
    completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
    {
        NSData *imageNSData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

        CGImageSourceRef imgSource = CGImageSourceCreateWithData((__bridge_retained CFDataRef)imageNSData, NULL);

        //get all the metadata in the image
        NSDictionary *metadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imgSource, 0, NULL);

        //make the metadata dictionary mutable so we can add properties to it
        NSMutableDictionary *metadataAsMutable = [metadata mutableCopy];

        NSMutableDictionary *EXIFDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy];
        NSMutableDictionary *GPSDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy];
        NSMutableDictionary *RAWDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyRawDictionary]mutableCopy];

        if(!EXIFDictionary)
            EXIFDictionary = [[NSMutableDictionary dictionary] init];

        if(!GPSDictionary)
            GPSDictionary = [[NSMutableDictionary dictionary] init];

        if(!RAWDictionary)
            RAWDictionary = [[NSMutableDictionary dictionary] init];


        [GPSDictionary setObject:[NSNumber numberWithFloat:37.795]
                          forKey:(NSString*)kCGImagePropertyGPSLatitude];

        [GPSDictionary setObject:@"N" forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];

        [GPSDictionary setObject:[NSNumber numberWithFloat:122.410]
                          forKey:(NSString*)kCGImagePropertyGPSLongitude];

        [GPSDictionary setObject:@"W" forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];

        [GPSDictionary setObject:@"2012:10:18"
                          forKey:(NSString*)kCGImagePropertyGPSDateStamp];

        [GPSDictionary setObject:[NSNumber numberWithFloat:300]
                          forKey:(NSString*)kCGImagePropertyGPSImgDirection];

        [GPSDictionary setObject:[NSNumber numberWithFloat:37.795]
                          forKey:(NSString*)kCGImagePropertyGPSDestLatitude];

        [GPSDictionary setObject:@"N" forKey:(NSString*)kCGImagePropertyGPSDestLatitudeRef];

        [GPSDictionary setObject:[NSNumber numberWithFloat:122.410]
                          forKey:(NSString*)kCGImagePropertyGPSDestLongitude];

        [GPSDictionary setObject:@"W" forKey:(NSString*)kCGImagePropertyGPSDestLongitudeRef];

        [EXIFDictionary setObject:@"[S.D.] kCGImagePropertyExifUserComment"
                           forKey:(NSString *)kCGImagePropertyExifUserComment];

        [EXIFDictionary setObject:[NSNumber numberWithFloat:69.999]
                           forKey:(NSString*)kCGImagePropertyExifSubjectDistance];


        //Add the modified Data back into the image’s metadata
        [metadataAsMutable setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyExifDictionary];
        [metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];
        [metadataAsMutable setObject:RAWDictionary forKey:(NSString *)kCGImagePropertyRawDictionary];


        CFStringRef UTI = CGImageSourceGetType(imgSource); //this is the type of image (e.g., public.jpeg)

        //this will be the data CGImageDestinationRef will write into
        NSMutableData *newImageData = [NSMutableData data];

        CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)newImageData, UTI, 1, NULL);

        if(!destination)
            NSLog(@"***Could not create image destination ***");

        //add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
        CGImageDestinationAddImageFromSource(destination, imgSource, 0, (__bridge CFDictionaryRef) metadataAsMutable);

        //tell the destination to write the image data and metadata into our data object.
        //It will return false if something goes wrong
        BOOL success = NO;
        success = CGImageDestinationFinalize(destination);

        if(!success)
            NSLog(@"***Could not create data from image destination ***");

        CIImage *testImage = [CIImage imageWithData:newImageData];
        NSDictionary *propDict = [testImage properties];
        NSLog(@"Final properties %@", propDict);

    }];

其中输出这:

Final properties info {
    ColorModel = RGB;
    DPIHeight = 72;
    DPIWidth = 72;
    Depth = 8;
    Orientation = 6;
    PixelHeight = 2448;
    PixelWidth = 3264;
    "{Exif}" =     {
        ApertureValue = "2.526069";
        BrightnessValue = "0.547474";
        ColorSpace = 1;
        ComponentsConfiguration =         (
            0,
            0,
            0,
            1
        );
        ExifVersion =         (
            2,
            2,
            1
        );
        ExposureMode = 0;
        ExposureProgram = 2;
        ExposureTime = "0.05";
        FNumber = "2.4";
        Flash = 16;
        FlashPixVersion =         (
            1,
            0
        );
        FocalLenIn35mmFilm = 35;
        FocalLength = "4.28";
        ISOSpeedRatings =         (
            320
        );
        MeteringMode = 5;
        PixelXDimension = 3264;
        PixelYDimension = 2448;
        SceneCaptureType = 0;
        SensingMethod = 2;
        ShutterSpeedValue = "4.321929";
        SubjectArea =         (
            1631,
            1223,
            881,
            881
        );
        SubjectDistance = "69.999";
        UserComment = "[S.D.] kCGImagePropertyExifUserComment";
        WhiteBalance = 0;
    };
    "{GPS}" =     {
        DateStamp = "2012:10:18";
        DestLatitude = "37.795";
        DestLatitudeRef = N;
        DestLongitude = "122.41";
        DestLongitudeRef = W;
        ImgDirection = 300;
        Latitude = "37.795";
        LatitudeRef = N;
        Longitude = "122.41";
        LongitudeRef = W;
    };
    "{JFIF}" =     {
        DensityUnit = 1;
        JFIFVersion =         (
            1,
            1
        );
        XDensity = 72;
        YDensity = 72;
    };
    "{TIFF}" =     {
        Orientation = 6;
        ResolutionUnit = 2;
        XResolution = 72;
        YResolution = 72;
        "_YCbCrPositioning" = 1;
    };
}

正如您所看到的所有的值现在正确地嵌入到 EXIF 头信息和我测试过,这正确写入与 JPG 相机胶卷。

享受 !:)


2017-08-30 18:26:08 wenhaiwang 阅读数 2477

1.Exif简介

可交换图像文件格式常被简称为Exif(Exchangeable image file format),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。

Exif可以附加于JPEG、TIFF、RIFF、EXIF、GPS等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。

Exif信息以0xFFE1作为开头标记,后两个字节表示Exif信息的长度。所以Exif信息最大为64 kB,而内部采用TIFF格式。

2.读取Exif信息

Exif信息是通过ImageIO框架来实现的,ImageIO框架在iOS中偏低层,所以提供的接口都是C风格的,关键数据也都是使用CoreFoundation进行存储。进行数据的操作也就需要CoreFoundation和上层Foundation之间进行桥接转换。

1. 获取图片文件

NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"YourPic" withExtension:@""];

2.创建CGImageSourceRef

CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)fileUrl, NULL);

3.利用imageSource获取全部ExifData

CFDictionaryRef imageInfo = CGImageSourceCopyPropertiesAtIndex(imageSource, 0,NULL);

4.从全部ExifData中取出EXIF文件

NSDictionary *exifDic = (__bridge NSDictionary *)CFDictionaryGetValue(imageInfo, kCGImagePropertyExifDictionary) ;

5.打印全部Exif信息及EXIF文件信息

NSLog(@"All Exif Info:%@",imageInfo);
NSLog(@"EXIF:%@",exifDic);

一张佳能相机拍摄的照片中的Exif信息:

All Exif Info:{
    ColorModel = RGB;
    DPIHeight = 200;
    DPIWidth = 200;
    Depth = 8;
    Orientation = 1;
    PixelHeight = 667;
    PixelWidth = 1000;
    ProfileName = "sRGB IEC61966-2.1";
    "{Exif}" =  {
        ApertureValue = "3.375";
        BodySerialNumber = 214014001512;
        ColorSpace = 1;
        ComponentsConfiguration =         (
            1,
            2,
            3,
            0
        );
        CustomRendered = 0;
        DateTimeDigitized = "2016:07:05 16:12:02";
        DateTimeOriginal = "2016:07:05 16:12:02";
        ExifVersion =         (
            2,
            3
        );
        ExposureBiasValue = 0;
        ExposureMode = 0;
        ExposureProgram = 3;
        ExposureTime = "0.0004";
        FNumber = "3.2";
        Flash = 16;
        FlashPixVersion =         (
            1,
            0
        );
        FocalLength = 168;
        FocalPlaneResolutionUnit = 2;
        FocalPlaneXResolution = "3545.827586206897";
        FocalPlaneYResolution = "3526.530612244898";
        ISOSpeedRatings =         (
            400
        );
        LensMake = "Canon 35mm f1.4";
        LensModel = "2016/09/21 11:04:31";
        LensSerialNumber = 0000c08f5f;
        LensSpecification =         (
            70,
            200,
            0,
            0
        );
        MeteringMode = 3;
        PixelXDimension = 1000;
        PixelYDimension = 667;
        RecommendedExposureIndex = 400;
        SceneCaptureType = 0;
        SensitivityType = 2;
        ShutterSpeedValue = "11.375";
        SubsecTime = 795;
        SubsecTimeDigitized = 30;
        SubsecTimeOriginal = 30;
        WhiteBalance = 0;
    };
    "{IPTC}" =     {
        DateCreated = 20160705;
        DigitalCreationDate = 20160705;
        DigitalCreationTime = 161202;
        TimeCreated = 161202;
    };
    "{JFIF}" =     {
        DensityUnit = 0;
        JFIFVersion =         (
            1,
            0,
            1
        );
        XDensity = 200;
        YDensity = 200;
    };
    "{TIFF}" =     {
        DateTime = "2016:07:08 16:45:32";
        Make = Canon;
        Model = "Canon EOS-1D X";
        Orientation = 1;
        ResolutionUnit = 2;
        Software = "ACDSee Pro 8";
        XResolution = 200;
        YResolution = 200;
    };
}

3.写入Exif信息

1. 获取图片中的EXIF文件和GPS文件

NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"YourImage"], 1);

CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);

NSDictionary *imageInfo = (__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);

NSMutableDictionary *metaDataDic = [imageInfo mutableCopy];
NSMutableDictionary *exifDic =[[metaDataDic objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy];
NSMutableDictionary *GPSDic =[[metaDataDic objectForKey:(NSString*)kCGImagePropertyGPSDictionary]mutableCopy];

2. 修改EXIF文件和GPS文件中的部分信息

[exifDic setObject:[NSNumber numberWithFloat:1234.3] forKey:(NSString *)kCGImagePropertyExifExposureTime];
[exifDic setObject:@"SenseTime" forKey:(NSString *)kCGImagePropertyExifLensModel];

[GPSDic setObject:@"N" forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
[GPSDic setObject:[NSNumber numberWithFloat:116.29353] forKey:(NSString*)kCGImagePropertyGPSLatitude];

[metaDataDic setObject:exifDic forKey:(NSString*)kCGImagePropertyExifDictionary];
[metaDataDic setObject:GPSDic forKey:(NSString*)kCGImagePropertyGPSDictionary];

3. 将修改后的文件写入至图片中

CFStringRef UTI = CGImageSourceGetType(source);
NSMutableData *newImageData = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)newImageData, UTI, 1,NULL);

//add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)metaDataDic);
CGImageDestinationFinalize(destination);

4. 保存图片

NSString *directoryDocuments =  NSTemporaryDirectory();
[newImageData writeToFile: directoryDocuments atomically:YES];

5. 查看修改后图片的Exif信息

CIImage *testImage = [CIImage imageWithData:newImageData];
NSDictionary *propDict = [testImage properties];
NSLog(@"Properties %@", propDict);

修改后的Exif信息:

Properties {
    ColorModel = RGB;
    Depth = 8;
    Orientation = 1;
    PixelHeight = 667;
    PixelWidth = 1000;
    ProfileName = "sRGB IEC61966-2.1";
    "{Exif}" =     {
        ColorSpace = 1;
        ExposureTime = "1234.3";
        LensModel = SenseTime;
        PixelXDimension = 1000;
        PixelYDimension = 667;
    };
    "{GPS}" =     {
        Latitude = "116.2935333333333";
        LatitudeRef = N;
    };
    "{JFIF}" =     {
        DensityUnit = 0;
        JFIFVersion =         (
            1,
            0,
            1
        );
        XDensity = 72;
        YDensity = 72;
    };
    "{TIFF}" =     {
        Orientation = 1;
    };
}

4.注意事项

关于无法修改Exif值的几点注意事项:

1. 传入的数据格式与Exif规定的不符

Exif的每条信息都有对应的数据类型,如:String Float... 如果数据类型传入错误将无法写入文件。

2. 传入的字段超过规定字段长度

3. 相互依赖的字段只添加了一个字段

在GPS文件中经纬度的度数的字段与经纬度的方向的字段相互依赖,修改经/纬度数需要经/纬方向字段的存在,否则修改无效。

5.外部链接



作者:飞行的孤独员FG
链接:http://www.jianshu.com/p/a542751d4ba3
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2016-08-08 17:22:15 qyh791414379 阅读数 2518


方法一:知道照片URL

//新建CGImageSourceRef对象

CGImageSourceRef*imageRef= CGImageSourceCreateWithURL((CFURLRef)imageUrl, NULL);

//获取照片信息

NSDictionary*imageProperty=(NSDictionary*)CGImageSourceCopyPropertiesAtIndex(_imageRef, 0, NULL);

//获取照片EXIF信息

NSDictionary*ExifDictionary= [imagePropertyvalueForKey:(NSString*)kCGImagePropertyExifDictionary];

  

方法二:从UIimage中获取

//将UIimage转换为NSData

NSData *imageData=UIImageJPEGRepresentation(self.currentPhoto.image, 1.0);

//将NSData转换为CFDataRef并新建CGImageSourceRef对象

CGImageSourceRefimageRef=CGImageSourceCreateWithData((CFDataRef)imageData, NULL);

NSDictionary*imageProperty=(NSDictionary*)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(imageRef,0, NULL));

NSDictionary*ExifDictionary=[imagePropertyvalueForKey:(NSString*)kCGImagePropertyExifDictionary];


使用imageIO获取图片的exif信息

一幅图片除了包含我们能看见的像素信息,背后还包含了拍摄时间,光圈大小,曝光等信息。UIImage类将这些细节信息都隐藏了起来,只提供我们关心的图片尺寸,图片方向等。我们可以通过imageIO框架获取到图片背后的所有信息,下面就让我们一起看看。

 

  imageIO框架是iOS中偏底层一点儿的框架,它内部提供的接口都是C风格的,关键数据也都是使用CoreFoundation进行存储。庆幸的是CoreFoundation中有很多数据类型都可以上层的数据Foundation框架中的数据类型进行无缝桥接。这也就大大方便了我们对图片信息的操作。

 

  CGImageSourceRef是整个imageIO的入口,通过它我们可以完成从文件的加载图片。加载完成以后我们就得到一个CGImageSourceRef,通过CGImageSourceRef我们就可以获取图片文件的大小,UTI(uniform type identifier),内部包含几张图片,访问每一张图片以及获取每张图片对应的exif信息等。

 

  你可能会有一个疑问,为什么会有几张图片呢?

 

  这块儿我解释一下,imageSourceRef和文件是一一对应的,通常我们见到的图片文件(例如jpg,png)内部都只有一张图片,这种情况我们通过CGImageSourceGetCount方法得到的就会是1。但是不能排除一个图片文件中会有多种图片的情况,例如gif文件,这个时候一个文件中就可能包含几张甚至几十张图片。前面我写的一片博客《IOS中如何解析并显示Gif》就是通过imageSource实现加载和解析gif的功能。

 

  下面是系统相机拍的照片的exif信息:

复制代码

代码如下:


image property: {

    ColorModel = RGB;

    DPIHeight = 72;

    DPIWidth = 72;

    Depth = 8;

    Orientation = 6;

    PixelHeight = 2448;

    PixelWidth = 3264;

    "{Exif}" =     {

        ApertureValue = "2.526069";

        BrightnessValue = "-0.5140446";

        ColorSpace = 1;

        ComponentsConfiguration =         (

            1,

            2,

            3,

            0

        );

        DateTimeDigitized = "2013:06:24 22:11:30";

        DateTimeOriginal = "2013:06:24 22:11:30";

        ExifVersion =         (

            2,

            2,

            1

        );

        ExposureMode = 0;

        ExposureProgram = 2;

        ExposureTime = "0.06666667";

        FNumber = "2.4";

        Flash = 16;

        FlashPixVersion =         (

            1,

            0

        );

        FocalLenIn35mmFilm = 33;

        FocalLength = "4.13";

        ISOSpeedRatings =         (

            400

        );

        MeteringMode = 3;

        PixelXDimension = 3264;

        PixelYDimension = 2448;

        SceneCaptureType = 0;

        SensingMethod = 2;

        ShutterSpeedValue = "3.906905";

        SubjectArea =         (

            2815,

            1187,

            610,

            612

        );

        WhiteBalance = 0;

    };

    "{GPS}" =     {

        Altitude = "27.77328";

        AltitudeRef = 0;

        Latitude = "22.5645";

        LatitudeRef = N;

        Longitude = "113.8886666666667";

        LongitudeRef = E;

        TimeStamp = "14:11:23.36";

    };

    "{TIFF}" =     {

        DateTime = "2013:06:24 22:11:30";

        Make = Apple;

        Model = "iPhone 5";

        Orientation = 6;

        ResolutionUnit = 2;

        Software = "6.1.4";

        XResolution = 72;

        YResolution = 72;

        "_YCbCrPositioning" = 1;

    };

}


  从中我们可以看出最开始的几项分别显示了当前图片的颜色模式,色深,x,y方向的DPI,实际像素以及图片的方向。我最开始看到这个方向时,心中一喜这不是UIImage中的imageOrientation,但是实验发现这个方向和UIImage中的imageOrientation并不相等,此处的方向是exif标准定义的方向,从1到8分别对应这UIImage中的8个方向,只是顺序不一样,它们对应关系如下:

 



复制代码

代码如下:


enum {

    exifOrientationUp = 1,      // UIImageOrientationUp

    exifOrientationDown = 3,    // UIImageOrientationDown

    exifOrientationLeft = 6,    // UIImageOrientationLeft

    exifOrientationRight = 8,   // UIImageOrientationRight

    

    // these four exifOrientation does not support by all camera, but IOS support these orientation

    exifOrientationUpMirrored = 2,          // UIImageOrientationUpMirrored

    exifOrientationDownMirrored = 4,        // UIImageOrientationDownMirrored

    exifOrientationLeftMirrored = 5,        // UIImageOrientationLeftMirrored

    exifOrientationRightMirrored = 7,       // UIImageOrientationRightMirrored

};

typedef NSInteger ExifOrientation; 


  目前市面上的大部分数码相机和手机都会内置一个方向感应器,拍出的照片中会写如方向信息,但是通常都只会有前四种方向。这几种Mirrored方向通常都是手机前置摄像头自拍的时候才会设置。

 

  exif为什么要搞这么一个方向呢?

 

  几乎所有的摄像头在出场的时候成相芯片都是有方向的,拍出来的照片的像素都是默认方向的。如果每拍一张照片就对这些像素进行旋转,如果数码相机每秒连拍20张来算,旋转操作将会非常耗时。更聪明的做法是拍照时只记录一个方向,然后显示的时候按方向显示出来即可。因此exif定义了一个标准的方向参数,只要读图的软件都来遵守规则,加载时候读取图片方向,然后做相应的旋转即可。这样既可以达到快速成像的目的,又能达到正确的显示,何乐而不为呢。

 

  常见的图片浏览和编辑软件都遵守这个规则,但是有一个我们最常用的看图软件(windows自带的看图程序)不会去读这个方向,因此我们将数码相机和手机拍出来的图片导入windows上时,会经常遇到方向错误的问题。不知道windows帝国是怎么想的,或许和定义exif的组织有什么过节吧。

 

  图片信息中除了上面看提到的那些,还有拍摄的GPS信息,iOS自带的相册软件中的地点tab就是按照GPS信息实现的。还有很多其他的信息,感兴趣的可以自己写个程序研究研究,这里就不展开了。

没有更多推荐了,返回首页