2017年11月5日日曜日

画像のメタデータを解析

画像のメタデータ、つまりEXIFの撮影データや、GPSの位置情報などを取り出す。

実際のメタデータはCIImageのpropertiesプロパティで取れる。
辞書の中の一部に配列が入れ子になってる。
let ciImage = CIImage(contentsOf: fileURL)
let metadata:[String:Any] = ciImage!.properties

辞書の中身は以下のよう。
{ }が辞書、( )が配列。
ISOSpeedRatingsのように要素1個の配列に入ってる場合もあるので注意。
辞書のKeyはColorModelとかの文字列でもいいが、kCGImagePropertyColorModelなどの定数があるのでそれを使うといい。ただし、CFStringなのでStringにキャストして使う。
“ ”で囲まれた数値は最初にNSNumberにキャストすると取り出せる場合が多い。
値がなくてnilの場合もあるので、Optionalとして、nilチェックもする。

辞書のトップレベル

辞書のトップレベルならそのままkeyで取れる。
let colorModel = metadata[kCGImagePropertyColorModel as String] as! String

辞書の2ndレベル

2ndレベル以降だと、一度入れ子になった辞書や配列を読み出さないといけない。
以下ではExifの中のExposureTime(シャッター速度)を取り出す。
let exifDict = metadata[kCGImagePropertyExifDictionary as String] as? [String:Any]
if let m = exifDict?[kCGImagePropertyExifExposureTime as String] as? NSNumber {
    let exposureTime = m.floatValue
}

つづいてISOSpeedRatings(ISO感度)を取り出す。
辞書の中の要素一個の配列に入ってる。
if let ISORateArr = exifDict?[kCGImagePropertyExifISOSpeedRatings as String] as? [Any] {
    if let rate = ISORateArr[0] as? NSNumber {
        let ISORate = exifDict[kCGImagePropertyExifISOSpeedRatings as String] = rate.stringValue
    }
}

メタデータの中身の例

{
    ColorModel = RGB;
    DPIHeight = 72;
    DPIWidth = 72;
    Depth = 8;
    Orientation = 1;
    PixelHeight = 2448;
    PixelWidth = 3264;
    ProfileName = "sRGB IEC61966-2.1";
    "{Exif}" =     {
        ApertureValue = "2.52606882168926";
        BrightnessValue = "2.661020629750272";
        ColorSpace = 1;
        ComponentsConfiguration =         (
            1,
            2,
            3,
            0
        );
        CustomRendered = 2;
        DateTimeDigitized = "2016:03:09 15:28:25";
        DateTimeOriginal = "2016:03:09 15:28:25";
        ExifVersion =         (
            2,
            2,
            1
        );
        ExposureBiasValue = 0;
        ExposureMode = 0;
        ExposureProgram = 2;
        ExposureTime = "0.0303030303030303";
        FNumber = "2.4";
        Flash = 32;
        FlashPixVersion =         (
            1,
            0
        );
        FocalLenIn35mmFilm = 31;
        FocalLength = "3.3";
        ISOSpeedRatings =         (
            160
        );
        LensMake = Apple;
        LensModel = "iPad Air 2 back camera 3.3mm f/2.4";
        LensSpecification =         (
            "3.3",
            "3.3",
            "2.4",
            "2.4"
        );
        MeteringMode = 5;
        PixelXDimension = 3264;
        PixelYDimension = 2448;
        SceneCaptureType = 0;
        SceneType = 1;
        SensingMethod = 2;
        ShutterSpeedValue = "5.058989898989899";
        SubjectArea =         (
            1631,
            1223,
            1795,
            1077
        );
        SubsecTimeDigitized = 996;
        SubsecTimeOriginal = 996;
        WhiteBalance = 0;
    };
    "{GPS}" =     {
        Altitude = "143.7687861271676";
        AltitudeRef = 0;
        DateStamp = "2016:03:09";
        DestBearing = "127.0993788819876";
        DestBearingRef = T;
        HPositioningError = 5;
        ImgDirection = "12x.xxx3788819876";
        ImgDirectionRef = T;
        Latitude = "36.588055";
        LatitudeRef = N;
        Longitude = "139.xxx3666666667";
        LongitudeRef = E;
        Speed = 0;
        SpeedRef = K;
        TimeStamp = "06:28:25";
    };
    "{MakerApple}" =     {
        1 = 4;
        10 = 2;
        14 = 1;
        2 = <37007700 73003500 34004c00 5c006c00 67007c00 75008500 a300b100 b000e400 6e006500 68003600 38005f00 62006c00 66007700 70007b00 8200b600 e200cd00 5800b900 9d009400 5f004300 52005e00 5c008100 8300b100 d000cf00 de000701 56006800 a8009700 7e005300 4c006600 7c008e00 9300ea00 1601f100 e900e300 53006100 83007c00 7e00c300 ca00b800 86008c00 9200f200 ff000101 d500b100 5e006200 6b00be00 4a016d01 7d018d01 5001cd00 a200c900 f800df00 e000af00 71009600 fd004d01 4b014401 4f014f01 6a01a201 44013a01 16012501 37019000 6f015801 0f01fc00 f800f000 f7002101 3f016a01 9001bb01 9b018101 4401f700 d500a200 e700d700 dc00e500 f500e800 18013b01 60019001 6a013001 12010b01 5f008000 9d00b200 9d009b00 b900c800 e7002a01 87017201 3401fa00 c800cb00 5c008000 91009400 85009900 9600af00 be005601 59012b01 e300d800 18012f01 6e008a00 7c007500 72008200 9100a500 e7006701 3a01c400 e9007601 8c018e01 41007100 63005c00 5f006c00 83009100 3a014f01 dc00fb00 9e019d01 aa01ad01 59005300 4f005500 52005d00 72000c01 53010b01 1701b001 a701a201 9b019c01 44005100 51005000 5200a400 0a014701 23010c01 af01b801 9f019c01 9701a601 36003800 48006700 d000f300 08014301 19018701 ad01b101 9c019901 93018a01>;
        20 = 3;
        3 =         {
            epoch = 0;
            flags = 1;
            timescale = 1000000000;
            value = 817736307596166;
        };
        4 = 1;
        5 = 214;
        6 = 220;
        7 = 1;
        8 =         (
            "-0.9269282",
            "0.0151294",
            "-0.3894437"
        );
    };
    "{TIFF}" =     {
        DateTime = "2016:03:09 15:28:25";
        Make = Apple;
        Model = "iPad Air 2";
        Orientation = 1;
        ResolutionUnit = 2;
        Software = "9.2.1";
        XResolution = 72;
        YResolution = 72;
    };

}

0 件のコメント:

コメントを投稿